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.

302 lines
8.5 KiB

  1. //+-------------------------------------------------------------------------
  2. // Microsoft Windows
  3. //
  4. // Copyright (C) Microsoft Corporation, 2001 - 2001
  5. //
  6. // File: fileutil.cpp
  7. //
  8. // Contents: File utility functions used by the minimal cryptographic
  9. // APIs.
  10. //
  11. // Functions: I_MinCryptMapFile
  12. //
  13. // History: 21-Jan-01 philh created
  14. //--------------------------------------------------------------------------
  15. #include "global.hxx"
  16. #ifdef _M_IX86
  17. //+=========================================================================
  18. // The following is taken from the following file:
  19. // \nt\ds\security\cryptoapi\common\unicode\reg.cpp
  20. //-=========================================================================
  21. BOOL WINAPI I_FIsWinNT(void) {
  22. static BOOL fIKnow = FALSE;
  23. static BOOL fIsWinNT = FALSE;
  24. OSVERSIONINFO osVer;
  25. if(fIKnow)
  26. return(fIsWinNT);
  27. memset(&osVer, 0, sizeof(OSVERSIONINFO));
  28. osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  29. if( GetVersionEx(&osVer) )
  30. fIsWinNT = (osVer.dwPlatformId == VER_PLATFORM_WIN32_NT);
  31. // even on an error, this is as good as it gets
  32. fIKnow = TRUE;
  33. return(fIsWinNT);
  34. }
  35. // make MBCS from Unicode string
  36. //
  37. // Include parameters specifying the length of the input wide character
  38. // string and return number of bytes converted. An input length of -1 indicates
  39. // null terminated.
  40. //
  41. // This extended version was added to handle REG_MULTI_SZ which contains
  42. // multiple null terminated strings.
  43. BOOL WINAPI I_MkMBStrEx(PBYTE pbBuff, DWORD cbBuff, LPCWSTR wsz, int cchW,
  44. char ** pszMB, int *pcbConverted) {
  45. int cbConverted;
  46. // sfield: don't bring in crt for assert. you get free assert via
  47. // an exception if these are null
  48. // assert(pszMB != NULL);
  49. *pszMB = NULL;
  50. // assert(pcbConverted != NULL);
  51. *pcbConverted = 0;
  52. if(wsz == NULL)
  53. return(TRUE);
  54. // how long is the mb string
  55. cbConverted = WideCharToMultiByte( 0,
  56. 0,
  57. wsz,
  58. cchW,
  59. NULL,
  60. 0,
  61. NULL,
  62. NULL);
  63. if (cbConverted <= 0)
  64. return(FALSE);
  65. // get a buffer long enough
  66. if(pbBuff != NULL && (DWORD) cbConverted <= cbBuff)
  67. *pszMB = (char *) pbBuff;
  68. else
  69. *pszMB = (char *) I_MemAlloc(cbConverted);
  70. if(*pszMB == NULL) {
  71. SetLastError(ERROR_OUTOFMEMORY);
  72. return(FALSE);
  73. }
  74. // now convert to MB
  75. *pcbConverted = WideCharToMultiByte(0,
  76. 0,
  77. wsz,
  78. cchW,
  79. *pszMB,
  80. cbConverted,
  81. NULL,
  82. NULL);
  83. return(TRUE);
  84. }
  85. // make MBCS from Unicode string
  86. BOOL WINAPI I_MkMBStr(PBYTE pbBuff, DWORD cbBuff, LPCWSTR wsz, char ** pszMB) {
  87. int cbConverted;
  88. return I_MkMBStrEx(pbBuff, cbBuff, wsz, -1, pszMB, &cbConverted);
  89. }
  90. void WINAPI I_FreeMBStr(PBYTE pbBuff, char * szMB) {
  91. if((szMB != NULL) && (pbBuff != (PBYTE)szMB))
  92. I_MemFree(szMB);
  93. }
  94. //+=========================================================================
  95. // The following was taken from the following file:
  96. // \nt\ds\security\cryptoapi\common\unicode\file.cpp
  97. //-=========================================================================
  98. HANDLE WINAPI I_CreateFileU (
  99. LPCWSTR lpFileName,
  100. DWORD dwDesiredAccess,
  101. DWORD dwShareMode,
  102. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  103. DWORD dwCreationDisposition,
  104. DWORD dwFlagsAndAttributes,
  105. HANDLE hTemplateFile
  106. ) {
  107. BYTE rgb[_MAX_PATH];
  108. char * szFileName;
  109. HANDLE hFile;
  110. if(I_FIsWinNT())
  111. return( CreateFileW (
  112. lpFileName,
  113. dwDesiredAccess,
  114. dwShareMode,
  115. lpSecurityAttributes,
  116. dwCreationDisposition,
  117. dwFlagsAndAttributes,
  118. hTemplateFile
  119. ));
  120. hFile = INVALID_HANDLE_VALUE;
  121. if(I_MkMBStr(rgb, _MAX_PATH, lpFileName, &szFileName))
  122. hFile = CreateFileA (
  123. szFileName,
  124. dwDesiredAccess,
  125. dwShareMode,
  126. lpSecurityAttributes,
  127. dwCreationDisposition,
  128. dwFlagsAndAttributes,
  129. hTemplateFile
  130. );
  131. I_FreeMBStr(rgb, szFileName);
  132. return(hFile);
  133. }
  134. #else
  135. #define I_CreateFileU CreateFileW
  136. #endif // _M_IX86
  137. //+-------------------------------------------------------------------------
  138. // Maps the file into memory.
  139. //
  140. // According to dwFileType, pvFile can be a pwszFilename, hFile or pFileBlob.
  141. // Only READ access is required.
  142. //
  143. // dwFileType:
  144. // MINCRYPT_FILE_NAME : pvFile - LPCWSTR pwszFilename
  145. // MINCRYPT_FILE_HANDLE : pvFile - HANDLE hFile
  146. // MINCRYPT_FILE_BLOB : pvFile - PCRYPT_DATA_BLOB pFileBlob
  147. //
  148. // *pFileBlob is updated with pointer to and length of the mapped file. For
  149. // MINCRYPT_FILE_NAME and MINCRYPT_FILE_HANDLE, UnmapViewOfFile() must
  150. // be called to free pFileBlob->pbData.
  151. //
  152. // All accesses to this mapped memory must be within __try / __except's.
  153. //--------------------------------------------------------------------------
  154. LONG
  155. WINAPI
  156. I_MinCryptMapFile(
  157. IN DWORD dwFileType,
  158. IN const VOID *pvFile,
  159. OUT PCRYPT_DATA_BLOB pFileBlob
  160. )
  161. {
  162. LONG lErr = ERROR_SUCCESS;
  163. switch (dwFileType) {
  164. case MINCRYPT_FILE_NAME:
  165. {
  166. LPCWSTR pwszInFilename = (LPCWSTR) pvFile;
  167. HANDLE hFile;
  168. hFile = I_CreateFileU(
  169. pwszInFilename,
  170. GENERIC_READ,
  171. FILE_SHARE_READ,
  172. NULL, // lpsa
  173. OPEN_EXISTING,
  174. FILE_ATTRIBUTE_NORMAL,
  175. NULL // hTemplateFile
  176. );
  177. if (INVALID_HANDLE_VALUE == hFile)
  178. goto CreateFileError;
  179. lErr = I_MinCryptMapFile(
  180. MINCRYPT_FILE_HANDLE,
  181. (const VOID *) hFile,
  182. pFileBlob
  183. );
  184. CloseHandle(hFile);
  185. }
  186. break;
  187. case MINCRYPT_FILE_HANDLE:
  188. {
  189. HANDLE hInFile = (HANDLE) pvFile;
  190. HANDLE hMappedFile;
  191. DWORD cbHighSize = 0;;
  192. DWORD cbLowSize;
  193. cbLowSize = GetFileSize(hInFile, &cbHighSize);
  194. if (INVALID_FILE_SIZE == cbLowSize)
  195. goto GetFileSizeError;
  196. if (0 != cbHighSize)
  197. goto Exceeded32BitFileSize;
  198. hMappedFile = CreateFileMappingA(
  199. hInFile,
  200. NULL, // lpFileMappingAttributes,
  201. PAGE_READONLY,
  202. 0, // dwMaximumSizeHigh
  203. 0, // dwMaximumSizeLow
  204. NULL // lpName
  205. );
  206. if (NULL == hMappedFile)
  207. goto CreateFileMappingError;
  208. pFileBlob->pbData = (BYTE *) MapViewOfFile(
  209. hMappedFile,
  210. FILE_MAP_READ,
  211. 0, // dwFileOffsetHigh
  212. 0, // dwFileOffsetLow
  213. 0 // dwNumberOfBytesToMap, 0 => entire file
  214. );
  215. CloseHandle(hMappedFile);
  216. if (NULL == pFileBlob->pbData)
  217. goto MapViewOfFileError;
  218. pFileBlob->cbData = cbLowSize;
  219. }
  220. break;
  221. case MINCRYPT_FILE_BLOB:
  222. {
  223. PCRYPT_DATA_BLOB pInFileBlob = (PCRYPT_DATA_BLOB) pvFile;
  224. *pFileBlob = *pInFileBlob;
  225. }
  226. break;
  227. default:
  228. goto InvalidParameter;
  229. }
  230. CommonReturn:
  231. return lErr;
  232. ErrorReturn:
  233. assert(ERROR_SUCCESS != lErr);
  234. pFileBlob->pbData = NULL;
  235. pFileBlob->cbData = 0;
  236. goto CommonReturn;
  237. InvalidParameter:
  238. lErr = ERROR_INVALID_PARAMETER;
  239. goto ErrorReturn;
  240. Exceeded32BitFileSize:
  241. lErr = ERROR_FILE_INVALID;
  242. goto ErrorReturn;
  243. CreateFileError:
  244. GetFileSizeError:
  245. CreateFileMappingError:
  246. MapViewOfFileError:
  247. lErr = GetLastError();
  248. if (ERROR_SUCCESS == lErr)
  249. lErr = ERROR_OPEN_FAILED;
  250. goto ErrorReturn;
  251. }