//+------------------------------------------------------------------------- // Microsoft Windows // // Copyright (C) Microsoft Corporation, 2001 - 2001 // // File: fileutil.cpp // // Contents: File utility functions used by the minimal cryptographic // APIs. // // Functions: I_MinCryptMapFile // // History: 21-Jan-01 philh created //-------------------------------------------------------------------------- #include "global.hxx" #ifdef _M_IX86 //+========================================================================= // The following is taken from the following file: // \nt\ds\security\cryptoapi\common\unicode\reg.cpp //-========================================================================= BOOL WINAPI I_FIsWinNT(void) { static BOOL fIKnow = FALSE; static BOOL fIsWinNT = FALSE; OSVERSIONINFO osVer; if(fIKnow) return(fIsWinNT); memset(&osVer, 0, sizeof(OSVERSIONINFO)); osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if( GetVersionEx(&osVer) ) fIsWinNT = (osVer.dwPlatformId == VER_PLATFORM_WIN32_NT); // even on an error, this is as good as it gets fIKnow = TRUE; return(fIsWinNT); } // make MBCS from Unicode string // // Include parameters specifying the length of the input wide character // string and return number of bytes converted. An input length of -1 indicates // null terminated. // // This extended version was added to handle REG_MULTI_SZ which contains // multiple null terminated strings. BOOL WINAPI I_MkMBStrEx(PBYTE pbBuff, DWORD cbBuff, LPCWSTR wsz, int cchW, char ** pszMB, int *pcbConverted) { int cbConverted; // sfield: don't bring in crt for assert. you get free assert via // an exception if these are null // assert(pszMB != NULL); *pszMB = NULL; // assert(pcbConverted != NULL); *pcbConverted = 0; if(wsz == NULL) return(TRUE); // how long is the mb string cbConverted = WideCharToMultiByte( 0, 0, wsz, cchW, NULL, 0, NULL, NULL); if (cbConverted <= 0) return(FALSE); // get a buffer long enough if(pbBuff != NULL && (DWORD) cbConverted <= cbBuff) *pszMB = (char *) pbBuff; else *pszMB = (char *) I_MemAlloc(cbConverted); if(*pszMB == NULL) { SetLastError(ERROR_OUTOFMEMORY); return(FALSE); } // now convert to MB *pcbConverted = WideCharToMultiByte(0, 0, wsz, cchW, *pszMB, cbConverted, NULL, NULL); return(TRUE); } // make MBCS from Unicode string BOOL WINAPI I_MkMBStr(PBYTE pbBuff, DWORD cbBuff, LPCWSTR wsz, char ** pszMB) { int cbConverted; return I_MkMBStrEx(pbBuff, cbBuff, wsz, -1, pszMB, &cbConverted); } void WINAPI I_FreeMBStr(PBYTE pbBuff, char * szMB) { if((szMB != NULL) && (pbBuff != (PBYTE)szMB)) I_MemFree(szMB); } //+========================================================================= // The following was taken from the following file: // \nt\ds\security\cryptoapi\common\unicode\file.cpp //-========================================================================= HANDLE WINAPI I_CreateFileU ( LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile ) { BYTE rgb[_MAX_PATH]; char * szFileName; HANDLE hFile; if(I_FIsWinNT()) return( CreateFileW ( lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile )); hFile = INVALID_HANDLE_VALUE; if(I_MkMBStr(rgb, _MAX_PATH, lpFileName, &szFileName)) hFile = CreateFileA ( szFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile ); I_FreeMBStr(rgb, szFileName); return(hFile); } #else #define I_CreateFileU CreateFileW #endif // _M_IX86 //+------------------------------------------------------------------------- // Maps the file into memory. // // According to dwFileType, pvFile can be a pwszFilename, hFile or pFileBlob. // Only READ access is required. // // dwFileType: // MINCRYPT_FILE_NAME : pvFile - LPCWSTR pwszFilename // MINCRYPT_FILE_HANDLE : pvFile - HANDLE hFile // MINCRYPT_FILE_BLOB : pvFile - PCRYPT_DATA_BLOB pFileBlob // // *pFileBlob is updated with pointer to and length of the mapped file. For // MINCRYPT_FILE_NAME and MINCRYPT_FILE_HANDLE, UnmapViewOfFile() must // be called to free pFileBlob->pbData. // // All accesses to this mapped memory must be within __try / __except's. //-------------------------------------------------------------------------- LONG WINAPI I_MinCryptMapFile( IN DWORD dwFileType, IN const VOID *pvFile, OUT PCRYPT_DATA_BLOB pFileBlob ) { LONG lErr = ERROR_SUCCESS; switch (dwFileType) { case MINCRYPT_FILE_NAME: { LPCWSTR pwszInFilename = (LPCWSTR) pvFile; HANDLE hFile; hFile = I_CreateFileU( pwszInFilename, GENERIC_READ, FILE_SHARE_READ, NULL, // lpsa OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL // hTemplateFile ); if (INVALID_HANDLE_VALUE == hFile) goto CreateFileError; lErr = I_MinCryptMapFile( MINCRYPT_FILE_HANDLE, (const VOID *) hFile, pFileBlob ); CloseHandle(hFile); } break; case MINCRYPT_FILE_HANDLE: { HANDLE hInFile = (HANDLE) pvFile; HANDLE hMappedFile; DWORD cbHighSize = 0;; DWORD cbLowSize; cbLowSize = GetFileSize(hInFile, &cbHighSize); if (INVALID_FILE_SIZE == cbLowSize) goto GetFileSizeError; if (0 != cbHighSize) goto Exceeded32BitFileSize; hMappedFile = CreateFileMappingA( hInFile, NULL, // lpFileMappingAttributes, PAGE_READONLY, 0, // dwMaximumSizeHigh 0, // dwMaximumSizeLow NULL // lpName ); if (NULL == hMappedFile) goto CreateFileMappingError; pFileBlob->pbData = (BYTE *) MapViewOfFile( hMappedFile, FILE_MAP_READ, 0, // dwFileOffsetHigh 0, // dwFileOffsetLow 0 // dwNumberOfBytesToMap, 0 => entire file ); CloseHandle(hMappedFile); if (NULL == pFileBlob->pbData) goto MapViewOfFileError; pFileBlob->cbData = cbLowSize; } break; case MINCRYPT_FILE_BLOB: { PCRYPT_DATA_BLOB pInFileBlob = (PCRYPT_DATA_BLOB) pvFile; *pFileBlob = *pInFileBlob; } break; default: goto InvalidParameter; } CommonReturn: return lErr; ErrorReturn: assert(ERROR_SUCCESS != lErr); pFileBlob->pbData = NULL; pFileBlob->cbData = 0; goto CommonReturn; InvalidParameter: lErr = ERROR_INVALID_PARAMETER; goto ErrorReturn; Exceeded32BitFileSize: lErr = ERROR_FILE_INVALID; goto ErrorReturn; CreateFileError: GetFileSizeError: CreateFileMappingError: MapViewOfFileError: lErr = GetLastError(); if (ERROR_SUCCESS == lErr) lErr = ERROR_OPEN_FAILED; goto ErrorReturn; }