Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

360 lines
9.3 KiB

  1. //*************************************************************
  2. //
  3. // Private Profile APIs wrapper to deal with long names
  4. //
  5. // Microsoft Confidential
  6. // Copyright (c) Microsoft Corporation 1997-2000
  7. // All rights reserved
  8. //
  9. //*************************************************************
  10. #include "uenv.h"
  11. #define CREATE_FILE_MAX_PATH MAX_PATH
  12. #define LONG_LOCAL_PATH_PREFIX TEXT("\\\\?\\")
  13. #define LONG_PATH_PREFIX_LEN 8
  14. #define IS_LONG_FILE_NAME(lpFileName) ((lpFileName[0] == TEXT('\\')) && (lpFileName[1] == TEXT('\\')) && (lpFileName[2] == TEXT('?')))
  15. //*************************************************************
  16. // ConvertToLongPath()
  17. //
  18. // Purpose: converts the given absolute path to long path names
  19. //
  20. // Parameters:
  21. //
  22. //
  23. // Return:
  24. // True if successful, False otherwise. GetLastError for more details
  25. //
  26. // Comments:
  27. //
  28. //*************************************************************
  29. BOOL ConvertToLongPath(LPCTSTR lpFileName, LPTSTR lpLongName)
  30. {
  31. //
  32. // Convert the path to long path..
  33. //
  34. if (!IS_LONG_FILE_NAME(lpFileName) &&
  35. (lstrlen(lpFileName) >= CREATE_FILE_MAX_PATH)) {
  36. //
  37. // Path is less than MAX_PATH or it is already a long path name
  38. //
  39. if (IsUNCPath(lpFileName)) {
  40. lstrcpy(lpLongName, LONG_UNC_PATH_PREFIX);
  41. lstrcat(lpLongName, lpFileName+1);
  42. }
  43. else {
  44. lstrcpy(lpLongName, LONG_LOCAL_PATH_PREFIX);
  45. lstrcat(lpLongName, lpFileName);
  46. }
  47. }
  48. else {
  49. lstrcpy(lpLongName, lpFileName);
  50. }
  51. return TRUE;
  52. }
  53. //*************************************************************
  54. // GetIniTmpFileName()
  55. //
  56. // Purpose: gets a temp file name to copy down the ini file
  57. //
  58. // Parameters:
  59. //
  60. //
  61. // Return:
  62. // True if successful, False otherwise. GetLastError for more details
  63. //
  64. // Comments:
  65. //
  66. //*************************************************************
  67. BOOL GetIniTmpFileName(LPTSTR szTempFile)
  68. {
  69. XPtrLF<TCHAR> xTmpPath;
  70. DWORD dwSizeRequired;
  71. szTempFile[0] = TEXT('\0');
  72. xTmpPath = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR)*MAX_PATH);
  73. if (!xTmpPath) {
  74. DebugMsg((DM_WARNING, TEXT("GetIniTmpFileName: Couldn't allocate memory for tmpfile path")));
  75. return FALSE;
  76. }
  77. //
  78. // get the temp path
  79. //
  80. dwSizeRequired = GetTempPath(MAX_PATH, xTmpPath);
  81. if (dwSizeRequired == 0) {
  82. DebugMsg((DM_WARNING, TEXT("GetIniTmpFileName: Couldn't gettemppath. Error %d"), GetLastError()));
  83. return FALSE;
  84. }
  85. if (dwSizeRequired >= MAX_PATH) {
  86. //
  87. // retry with a larger buffer
  88. //
  89. xTmpPath = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR)*dwSizeRequired);
  90. if (!xTmpPath) {
  91. DebugMsg((DM_WARNING, TEXT("GetIniTmpFileName: Couldn't allocate memory for tmpfile path(2)")));
  92. return FALSE;
  93. }
  94. dwSizeRequired = GetTempPath(dwSizeRequired, xTmpPath);
  95. if (dwSizeRequired == 0) {
  96. DebugMsg((DM_WARNING, TEXT("GetIniTmpFileName: Couldn't gettemppath. Error %d"), GetLastError()));
  97. return FALSE;
  98. }
  99. }
  100. //
  101. // Now get a temp file in the temp directory
  102. //
  103. if (!GetTempFileName(xTmpPath, TEXT("ini"), 0, szTempFile)) {
  104. DebugMsg((DM_WARNING, TEXT("GetIniTmpFileName: Couldn't gettempfilename. Error - %d"), GetLastError()));
  105. return FALSE;
  106. }
  107. return TRUE;
  108. }
  109. //*************************************************************
  110. //
  111. // MyGetPrivateProfileString()
  112. //
  113. // Purpose: A version of PrivateProfileString that takes long UNC Path
  114. //
  115. // Parameters:
  116. //
  117. //
  118. // Return:
  119. // True if successful, False otherwise. GetLastError for more details
  120. //
  121. // Comments:
  122. //
  123. // This returns TRUE or false based on whether it managed to read
  124. // successfully. In a case where it fails it will copy the default to
  125. // the output string GetLastError for more details
  126. //*************************************************************
  127. DWORD MyGetPrivateProfileString(LPCTSTR lpAppName, LPCTSTR lpKeyName,
  128. LPCTSTR lpDefault, LPTSTR lpReturnedString,
  129. DWORD nSize, LPCTSTR lpFileName)
  130. {
  131. XPtrLF<TCHAR> xSrcBuf;
  132. TCHAR szTempFile[MAX_PATH+1];
  133. DWORD dwSize;
  134. DWORD dwRet=0;
  135. //
  136. // copy the default string first
  137. //
  138. lstrcpy(lpReturnedString, lpDefault);
  139. //
  140. // get the temp file name
  141. //
  142. if (!GetIniTmpFileName(szTempFile)) {
  143. return 0;
  144. }
  145. xSrcBuf = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR)*(lstrlen(lpFileName)+1+LONG_PATH_PREFIX_LEN));
  146. if (!xSrcBuf) {
  147. DebugMsg((DM_WARNING, TEXT("MyGetPrivateProfileString: Couldn't allocate memory for filename")));
  148. return 0;
  149. }
  150. //
  151. // Convert the given path to a long name..
  152. //
  153. ConvertToLongPath(lpFileName, xSrcBuf);
  154. DebugMsg((DM_VERBOSE, TEXT("MyGetPrivateProfileString: Reading from File <%s>"), xSrcBuf));
  155. //
  156. // copy the ini file to the local path
  157. //
  158. if (!CopyFile(xSrcBuf, szTempFile, FALSE)) {
  159. DebugMsg((DM_WARNING, TEXT("MyGetPrivateProfileString: Couldn't copy file to temp file. Error %d"), GetLastError()));
  160. return 0;
  161. }
  162. //
  163. // Now call the proper API
  164. //
  165. dwRet = GetPrivateProfileString(lpAppName, lpKeyName, lpDefault, lpReturnedString, nSize, szTempFile);
  166. //
  167. // Delete it once we are done
  168. //
  169. DeleteFile(szTempFile);
  170. DebugMsg((DM_VERBOSE, TEXT("MyGetPrivateProfileString: Read value %s from File <%s>"), lpReturnedString, xSrcBuf));
  171. return dwRet;
  172. }
  173. //*************************************************************
  174. //
  175. // MyGetPrivateProfileInt()
  176. //
  177. // Purpose: A version of PrivateProfileInt that takes long UNC Path
  178. //
  179. // Parameters:
  180. //
  181. //
  182. // Return:
  183. // True if successful, False otherwise. GetLastError for more details
  184. //
  185. // Comments:
  186. //
  187. // This returns TRUE or false based on whether it managed to read
  188. // successfully. In a case where it fails it will copy the default to
  189. // the output string GetLastError for more details
  190. //*************************************************************
  191. UINT MyGetPrivateProfileInt(LPCTSTR lpAppName, LPCTSTR lpKeyName,
  192. INT nDefault, LPCTSTR lpFileName)
  193. {
  194. XPtrLF<TCHAR> xSrcBuf;
  195. TCHAR szTempFile[MAX_PATH+1];
  196. DWORD dwSize, dwSizeRequired;
  197. UINT uRet=nDefault;
  198. if (!GetIniTmpFileName(szTempFile)) {
  199. return 0;
  200. }
  201. xSrcBuf = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR)*(lstrlen(lpFileName)+1+LONG_PATH_PREFIX_LEN));
  202. if (!xSrcBuf) {
  203. DebugMsg((DM_WARNING, TEXT("MyGetPrivateProfileString: Couldn't allocate memory for filename")));
  204. return 0;
  205. }
  206. ConvertToLongPath(lpFileName, xSrcBuf);
  207. DebugMsg((DM_VERBOSE, TEXT("MyGetPrivateProfileString: Reading from File <%s>"), xSrcBuf));
  208. if (!CopyFile(xSrcBuf, szTempFile, FALSE)) {
  209. DebugMsg((DM_WARNING, TEXT("MyGetPrivateProfileString: Couldn't copy file to temp file. Error %d"), GetLastError()));
  210. return 0;
  211. }
  212. uRet = GetPrivateProfileInt(lpAppName, lpKeyName, nDefault, szTempFile);
  213. DeleteFile(szTempFile);
  214. DebugMsg((DM_VERBOSE, TEXT("MyGetPrivateProfileString: Read value %d from File <%s>"), uRet, xSrcBuf));
  215. return uRet;
  216. }
  217. //*************************************************************
  218. //
  219. // MyWritePrivateProfileString()
  220. //
  221. // Purpose: A version of PrivateProfileString that takes long UNC Path
  222. //
  223. // Parameters:
  224. //
  225. //
  226. // Return:
  227. // True if successful, False otherwise. GetLastError for more details
  228. //
  229. // Comments:
  230. //
  231. // This returns TRUE or false based on whether it managed to read
  232. // successfully. In a case where it fails it will copy the default to
  233. // the output string GetLastError for more details
  234. //*************************************************************
  235. DWORD MyWritePrivateProfileString( LPCTSTR lpAppName, LPCTSTR lpKeyName,
  236. LPTSTR lpString, LPCTSTR lpFileName)
  237. {
  238. XPtrLF<TCHAR> xSrcBuf;
  239. TCHAR szTempFile[MAX_PATH+1];
  240. DWORD dwSize, dwSizeRequired, dwRet=0;
  241. if (!GetIniTmpFileName(szTempFile)) {
  242. return 0;
  243. }
  244. xSrcBuf = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR)*(lstrlen(lpFileName)+1+LONG_PATH_PREFIX_LEN));
  245. if (!xSrcBuf) {
  246. DebugMsg((DM_WARNING, TEXT("MyWritePrivateProfileString: Couldn't allocate memory for filename")));
  247. return 0;
  248. }
  249. ConvertToLongPath(lpFileName, xSrcBuf);
  250. DebugMsg((DM_VERBOSE, TEXT("MyWritePrivateProfileString: Writing to File <%s>"), xSrcBuf));
  251. if (!CopyFile(xSrcBuf, szTempFile, FALSE)) {
  252. if (GetLastError() != ERROR_FILE_NOT_FOUND) {
  253. DebugMsg((DM_WARNING, TEXT("MyWritePrivateProfileString: Couldn't copy file to temp file. Error %d"), GetLastError()));
  254. return 0;
  255. }
  256. }
  257. if (!(dwRet = WritePrivateProfileString(lpAppName, lpKeyName, lpString, szTempFile))) {
  258. DebugMsg((DM_WARNING, TEXT("MyWritePrivateProfileString: Couldn't Write to temp file. Error %d"), GetLastError()));
  259. goto Exit;
  260. }
  261. if (!CopyFile(szTempFile, xSrcBuf, FALSE)) {
  262. DebugMsg((DM_WARNING, TEXT("MyWritePrivateProfileString: Couldn't copy temp ini file to <%s> file. Error %d"), xSrcBuf, GetLastError()));
  263. goto Exit;
  264. }
  265. DeleteFile(szTempFile);
  266. return dwRet;
  267. Exit:
  268. DeleteFile(szTempFile);
  269. return 0;
  270. }