windows-nt/Source/XPSP1/NT/ds/security/cryptoapi/mincrypt/lib/fileutil.cpp

303 lines
8.5 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
//+-------------------------------------------------------------------------
// 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;
}