📄 contman.c
字号:
hFile = CreateFileW(
wszFilePath,
dwDesiredAccess,
dwShareMode,
NULL,
dwCreationDisposition,
dwAttribs | FILE_FLAG_BACKUP_SEMANTICS,
NULL
);
if (INVALID_HANDLE_VALUE != hFile)
{
fSetLastError = FALSE;
}
}
}
}
Ret:
if (hToken)
{
CloseHandle(hToken);
}
if (fSetLastError)
{
SetLastError(dwErr);
}
return hFile;
}
DWORD OpenFileInStorageArea(
IN BOOL fMachineKeyset,
IN DWORD dwDesiredAccess,
IN LPCWSTR wszUserStorageArea,
IN LPCWSTR wszFileName,
IN OUT HANDLE *phFile
)
{
LPWSTR wszFilePath = NULL;
// DWORD cbUserStorageArea;
// DWORD cbFileName;
DWORD dwShareMode = 0;
DWORD dwCreationDistribution = OPEN_EXISTING;
DWORD dwRetryCount;
DWORD dwAttribs = 0;
DWORD dwLastError = ERROR_SUCCESS;
*phFile = INVALID_HANDLE_VALUE;
if( dwDesiredAccess & GENERIC_READ ) {
dwShareMode |= FILE_SHARE_READ;
dwCreationDistribution = OPEN_EXISTING;
}
if( dwDesiredAccess & GENERIC_WRITE ) {
dwShareMode = 0;
dwCreationDistribution = OPEN_ALWAYS;
dwAttribs = FILE_ATTRIBUTE_SYSTEM;
}
if (0 != (dwLastError = GetFilePath(wszUserStorageArea, wszFileName,
&wszFilePath)))
{
goto Ret;
}
dwRetryCount = 0;
while (1)
{
*phFile = MyCreateFile(fMachineKeyset,
wszFilePath,
dwDesiredAccess,
dwShareMode,
dwCreationDistribution,
dwAttribs | FILE_FLAG_SEQUENTIAL_SCAN
);
if( *phFile == INVALID_HANDLE_VALUE )
{
dwLastError = GetLastError();
if (((ERROR_SHARING_VIOLATION == dwLastError) ||
(ERROR_ACCESS_DENIED == dwLastError)) &&
(MAX_CREATE_FILE_RETRY_COUNT > dwRetryCount))
{
Sleep(rgdwCreateFileRetryMilliseconds[dwRetryCount]);
dwRetryCount++;
}
else
{
goto Ret;
}
}
else
{
break;
}
}
Ret:
if(wszFilePath)
ContInfoFree(wszFilePath);
return dwLastError;
}
DWORD FindClosestFileInStorageArea(
IN LPCWSTR pwszUserStorageArea,
IN LPCSTR pszContainer,
OUT LPWSTR pwszNewFileName,
IN OUT HANDLE *phFile
)
{
LPWSTR pwszFilePath = NULL;
WCHAR rgwszNewFileName[35];
// DWORD cbUserStorageArea;
// DWORD cbFileName;
DWORD dwShareMode = 0;
DWORD dwCreationDistribution = OPEN_EXISTING;
HANDLE hFind = INVALID_HANDLE_VALUE;
WIN32_FIND_DATAW FindData;
DWORD dwLastError = ERROR_SUCCESS;
memset(&FindData, 0, sizeof(FindData));
memset(rgwszNewFileName, 0, sizeof(rgwszNewFileName));
*phFile = INVALID_HANDLE_VALUE;
dwShareMode |= FILE_SHARE_READ;
dwCreationDistribution = OPEN_EXISTING;
// get the stringized hash of the container name
if (0 != (dwLastError = GetHashOfContainer(pszContainer, rgwszNewFileName)))
{
goto Ret;
}
// ContInfoAlloc zeros memory so no need to set NULL terminator
rgwszNewFileName[32] = '_';
rgwszNewFileName[33] = '*';
if (0 != (dwLastError = GetFilePath(pwszUserStorageArea, rgwszNewFileName,
&pwszFilePath)))
{
goto Ret;
}
hFind = FindFirstFileExW(
pwszFilePath,
FindExInfoStandard,
&FindData,
FindExSearchNameMatch,
NULL,
0
);
if( hFind == INVALID_HANDLE_VALUE )
{
dwLastError = NTE_BAD_KEYSET;
goto Ret;
}
ContInfoFree(pwszFilePath);
pwszFilePath = NULL;
if (0 != (dwLastError = GetFilePath(pwszUserStorageArea, FindData.cFileName,
&pwszFilePath)))
{
goto Ret;
}
*phFile = CreateFileW(
pwszFilePath,
GENERIC_READ,
dwShareMode,
NULL,
dwCreationDistribution,
FILE_FLAG_SEQUENTIAL_SCAN,
NULL
);
if( *phFile == INVALID_HANDLE_VALUE )
{
dwLastError = NTE_BAD_KEYSET;
goto Ret;
}
// allocate and copy in the real file name to be returned
wcscpy(pwszNewFileName, FindData.cFileName);
Ret:
if (hFind)
FindClose(hFind);
if(pwszFilePath)
ContInfoFree(pwszFilePath);
return dwLastError;
}
//
// This function gets the determines if the user associated with the
// specified token is the Local System account.
//
DWORD ZeroizeFile(
IN LPCWSTR wszFilePath
)
{
HANDLE hFile = INVALID_HANDLE_VALUE;
BYTE *pb = NULL;
DWORD cb;
DWORD dwBytesWritten = 0;
DWORD dwErr = ERROR_SUCCESS;
if (INVALID_HANDLE_VALUE == (hFile = CreateFileW(wszFilePath,
GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_SYSTEM,
NULL)))
{
dwErr = (DWORD)NTE_BAD_KEYSET;
goto Ret;
}
if (0xFFFFFFFF == (cb = GetFileSize(hFile, NULL)))
{
dwErr = (DWORD)NTE_BAD_KEYSET;
goto Ret;
}
if (NULL == (pb = ContInfoAlloc(cb)))
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
goto Ret;
}
if (!WriteFile(hFile, pb, cb, &dwBytesWritten, NULL))
{
dwErr = (DWORD)NTE_BAD_KEYSET;
goto Ret;
}
if (cb != dwBytesWritten)
{
dwErr = (DWORD)NTE_FAIL;
}
Ret:
if (pb)
ContInfoFree(pb);
if (INVALID_HANDLE_VALUE != hFile)
CloseHandle(hFile);
return dwErr;
}
DWORD DeleteFileInStorageArea(
IN LPCWSTR wszUserStorageArea,
IN LPCWSTR wszFileName
)
{
LPWSTR wszFilePath = NULL;
DWORD cbUserStorageArea;
DWORD cbFileName;
DWORD dwErr = ERROR_SUCCESS;
cbUserStorageArea = wcslen( wszUserStorageArea ) * sizeof(WCHAR);
cbFileName = wcslen( wszFileName ) * sizeof(WCHAR);
wszFilePath = (LPWSTR)ContInfoAlloc( (cbUserStorageArea + cbFileName + 1) * sizeof(WCHAR) );
if( wszFilePath == NULL )
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
goto Ret;
}
CopyMemory(wszFilePath, wszUserStorageArea, cbUserStorageArea);
CopyMemory((LPBYTE)wszFilePath + cbUserStorageArea, wszFileName,
cbFileName + sizeof(WCHAR));
// write a file of the same size with all zeros first
if (ERROR_SUCCESS != (dwErr = ZeroizeFile(wszFilePath)))
goto Ret;
if (!DeleteFileW(wszFilePath))
{
dwErr = GetLastError();
SetLastError((DWORD)NTE_BAD_KEYSET);
}
Ret:
if(wszFilePath)
ContInfoFree(wszFilePath);
return dwErr;
}
DWORD SetContainerUserName(
IN LPSTR pszUserName,
IN PKEY_CONTAINER_INFO pContInfo
)
{
DWORD dwErr = 0;
if (NULL == (pContInfo->pszUserName =
(LPSTR)ContInfoAlloc((strlen(pszUserName) + 1) * sizeof(CHAR))))
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
goto Ret;
}
strcpy(pContInfo->pszUserName, pszUserName);
Ret:
return dwErr;
}
DWORD NT5ToNT5Migration(
IN DWORD dwProvType,
IN BOOL fMachineKeyset,
IN LPSTR pszContainer,
IN LPWSTR pwszFilePath,
IN DWORD dwFlags,
OUT PKEY_CONTAINER_INFO pContInfo,
OUT HANDLE *phFile
)
{
LPWSTR pwszOldFilePath = NULL;
LPWSTR pwszOldFullFilePath = NULL;
LPWSTR pwszNewFullFilePath = NULL;
LPWSTR pwszFileName = NULL;
BOOL fAllocedFileName = FALSE;
BOOL fIsLocalSystem;
BOOL fRetryWithHashedName = TRUE;
DWORD cch = 0;
DWORD dwErr = 0;
// get the correct storage area (directory)
if (0 != (dwErr = GetUserStorageArea(dwProvType,
fMachineKeyset,
TRUE,
&fIsLocalSystem,
&pwszOldFilePath)))
{
goto Ret;
}
// check if the length of the container name is the length of a new unique container,
// then try with the container name which was passed in, if this fails
// then try with the container name with the machine GUID appended
if (69 == strlen(pszContainer))
{
// convert to UNICODE pszContainer -> pwszFileName
if (0 == (cch = MultiByteToWideChar(CP_ACP, MB_COMPOSITE,
pszContainer,
-1, NULL, cch)))
{
dwErr = GetLastError();
goto Ret;
}
if (NULL == (pwszFileName = ContInfoAlloc((cch + 1) * sizeof(WCHAR))))
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
goto Ret;
}
fAllocedFileName = TRUE;
if (0 == (cch = MultiByteToWideChar(CP_ACP, MB_COMPOSITE,
pszContainer,
-1, pwszFileName, cch)))
{
dwErr = GetLastError();
goto Ret;
}
if (ERROR_SUCCESS != OpenFileInStorageArea(fMachineKeyset,
GENERIC_READ,
pwszOldFilePath,
pwszFileName,
phFile))
{
ContInfoFree(pwszFileName);
pwszFileName = NULL;
fAllocedFileName = FALSE;
fRetryWithHashedName = TRUE;
}
else
{
fRetryWithHashedName = FALSE;
}
}
if (fRetryWithHashedName)
{
pwszFileName = pContInfo->rgwszFileName;
if(ERROR_SUCCESS != (dwErr = OpenFileInStorageArea(fMachineKeyset,
GENERIC_READ,
pwszOldFilePath,
pwszFileName,
phFile)))
{
if ((ERROR_ACCESS_DENIED == dwErr) && (dwFlags & CRYPT_NEWKEYSET))
{
dwErr = (DWORD)NTE_EXISTS;
}
goto Ret;
}
}
// found an old file so move it to the new directory
CloseHandle(*phFile);
*phFile = INVALID_HANDLE_VALUE;
if (0 != (dwErr = GetFilePath(pwszOldFilePath, pwszFileName, &pwszOldFullFilePath)))
{
goto Ret;
}
if (0 != (dwErr = GetFilePath(pwszFilePath, pwszFileName, &pwszNewFullFilePath)))
{
goto Ret;
}
if (!MoveFileW(pwszOldFullFilePath, pwszNewFullFilePath))
{
dwErr = GetLastError();
goto Ret;
}
if(ERROR_SUCCESS != (dwErr = OpenFileInStorageArea(fMachineKeyset,
GENERIC_READ,
pwszFilePath,
pwszFileName,
phFile)))
{
goto Ret;
}
Ret:
if (fAllocedFileName && (NULL != pwszFileName))
{
ContInfoFree(pwszFileName);
}
if (pwszOldFullFilePath)
ContInfoFree(pwszOldFullFilePath);
if (pwszNewFullFilePath)
ContInfoFree(pwszNewFullFilePath);
if (pwszOldFilePath)
ContInfoFree(pwszOldFilePath);
return dwErr;
}
DWORD ReadContainerInfo(
IN DWORD dwProvType,
IN LPSTR pszContainerName,
IN BOOL fMachineKeyset,
IN DWORD dwFlags,
OUT PKEY_CONTAINER_INFO pContInfo
)
{
HANDLE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -