mirror of https://github.com/tongzx/nt5src
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.
641 lines
19 KiB
641 lines
19 KiB
/*==========================================================================
|
|
*
|
|
* Copyright (C) 1999-2000 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* File: enum.cpp
|
|
* Content Handles all of the file caching of device caps.
|
|
*
|
|
*
|
|
***************************************************************************/
|
|
#include "ddrawpr.h"
|
|
#include <stdio.h>
|
|
|
|
#include "d3dobj.hpp"
|
|
#include "enum.hpp"
|
|
#include "d3di.hpp"
|
|
#include "shlobj.h"
|
|
|
|
#define DXCACHEFILENAME "\\d3d8caps.dat"
|
|
#define DXTEMPFILENAME "\\d3d8caps.tmp"
|
|
|
|
typedef struct _FDEVICEHEADER
|
|
{
|
|
DWORD VendorId;
|
|
DWORD DeviceId;
|
|
DWORD SubSysId;
|
|
DWORD Revision;
|
|
DWORD FileOffset;
|
|
DWORD Size;
|
|
} FDEVICEHEADER;
|
|
|
|
HANDLE OpenCacheFile(DWORD dwDesiredAccess, DWORD dwCreationDisposition, char * pName, char * pPath)
|
|
{
|
|
char FName[MAX_PATH + 16];
|
|
|
|
GetSystemDirectory(FName, MAX_PATH);
|
|
|
|
lstrcat(FName, pName);
|
|
|
|
HANDLE h = CreateFile( FName,
|
|
dwDesiredAccess,
|
|
FILE_SHARE_READ,
|
|
NULL,
|
|
dwCreationDisposition,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL);
|
|
#ifdef WINNT
|
|
if (INVALID_HANDLE_VALUE == h)
|
|
{
|
|
HMODULE hShlwapi=0;
|
|
typedef HRESULT (WINAPI * PSHGETSPECIALFOLDERPATH) (HWND, LPTSTR, int, BOOL);
|
|
PSHGETSPECIALFOLDERPATH pSHGetSpecialFolderPath=0;
|
|
|
|
hShlwapi = LoadLibrary("SHELL32.DLL");
|
|
if (hShlwapi)
|
|
{
|
|
pSHGetSpecialFolderPath = (PSHGETSPECIALFOLDERPATH) GetProcAddress(hShlwapi,"SHGetSpecialFolderPathA");
|
|
|
|
if(pSHGetSpecialFolderPath)
|
|
{
|
|
HRESULT hr = pSHGetSpecialFolderPath(
|
|
NULL,
|
|
FName,
|
|
CSIDL_LOCAL_APPDATA, // <user name>\Local Settings\Applicaiton Data (non roaming)
|
|
TRUE);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
lstrcat(FName, pName);
|
|
|
|
h = CreateFile( FName,
|
|
dwDesiredAccess,
|
|
FILE_SHARE_READ,
|
|
NULL,
|
|
dwCreationDisposition,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL);
|
|
}
|
|
}
|
|
FreeLibrary(hShlwapi);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (pPath)
|
|
{
|
|
lstrcpy(pPath, FName);
|
|
}
|
|
return h;
|
|
}
|
|
|
|
void ReadFromCache(D3DADAPTER_IDENTIFIER8* pDI,
|
|
UINT* pCapsSize,
|
|
BYTE** ppCaps)
|
|
{
|
|
HANDLE h;
|
|
DWORD HeaderSize;
|
|
DWORD NumRead;
|
|
FDEVICEHEADER* pHeaderInfo = NULL;
|
|
DWORD i;
|
|
|
|
// Get the data for the device that we're looking for
|
|
|
|
*pCapsSize = 0;
|
|
*ppCaps = NULL;
|
|
|
|
// Open the file and look for the device entry
|
|
|
|
h = OpenCacheFile (GENERIC_READ, OPEN_EXISTING, DXCACHEFILENAME, NULL);
|
|
if (h == INVALID_HANDLE_VALUE)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ReadFile( h, &HeaderSize, sizeof(DWORD), &NumRead, NULL);
|
|
if (NumRead < sizeof(DWORD))
|
|
{
|
|
goto FileError;
|
|
}
|
|
pHeaderInfo = (FDEVICEHEADER*) MemAlloc(HeaderSize);
|
|
if (pHeaderInfo == NULL)
|
|
{
|
|
goto FileError;
|
|
}
|
|
ReadFile( h, pHeaderInfo, HeaderSize, &NumRead, NULL);
|
|
if (NumRead < HeaderSize)
|
|
{
|
|
goto FileError;
|
|
}
|
|
|
|
for (i = 0; i < HeaderSize / sizeof(FDEVICEHEADER); i++)
|
|
{
|
|
if ((pHeaderInfo[i].VendorId == pDI->VendorId) &&
|
|
(pHeaderInfo[i].DeviceId == pDI->DeviceId) &&
|
|
(pHeaderInfo[i].SubSysId == pDI->SubSysId) &&
|
|
(pHeaderInfo[i].Revision == pDI->Revision))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if (i < HeaderSize / sizeof(FDEVICEHEADER))
|
|
{
|
|
// We have info for the device - now we read it
|
|
|
|
if (SetFilePointer (h, pHeaderInfo[i].FileOffset, NULL, FILE_BEGIN) !=
|
|
pHeaderInfo[i].FileOffset)
|
|
{
|
|
goto FileError;
|
|
}
|
|
*ppCaps = (BYTE*) MemAlloc(pHeaderInfo[i].Size);
|
|
if (*ppCaps == NULL)
|
|
{
|
|
goto FileError;
|
|
}
|
|
ReadFile( h, *ppCaps, pHeaderInfo[i].Size, &NumRead, NULL);
|
|
if (NumRead < pHeaderInfo[i].Size)
|
|
{
|
|
MemFree(*ppCaps);
|
|
*ppCaps = NULL;
|
|
goto FileError;
|
|
}
|
|
|
|
// If we got this far, then everything worked
|
|
|
|
*pCapsSize = pHeaderInfo[i].Size;
|
|
}
|
|
|
|
FileError:
|
|
if (pHeaderInfo != NULL)
|
|
{
|
|
MemFree(pHeaderInfo);
|
|
}
|
|
CloseHandle(h);
|
|
}
|
|
|
|
|
|
void WriteToCache(D3DADAPTER_IDENTIFIER8* pDI,
|
|
UINT CapsSize,
|
|
BYTE* pCaps)
|
|
{
|
|
char FName[MAX_PATH + 16];
|
|
char NewFName[MAX_PATH + 16];
|
|
BOOL bNewFile = FALSE;
|
|
HANDLE hOld;
|
|
HANDLE hNew;
|
|
DWORD NewHeaderSize;
|
|
DWORD OldHeaderSize;
|
|
DWORD NumWritten;
|
|
DWORD NumRead;
|
|
FDEVICEHEADER* pOldHeaderInfo = NULL;
|
|
FDEVICEHEADER* pNewHeaderInfo = NULL;
|
|
DWORD dwOffset;
|
|
DWORD i;
|
|
DWORD NewEntries;
|
|
DWORD NextEntry;
|
|
DWORD Biggest;
|
|
BYTE* pBuffer = NULL;
|
|
|
|
// Does the file already exist, or do we need to create a new one?
|
|
hOld = OpenCacheFile (GENERIC_READ, OPEN_EXISTING, DXCACHEFILENAME, FName);
|
|
|
|
if (hOld == INVALID_HANDLE_VALUE)
|
|
{
|
|
bNewFile = TRUE;
|
|
}
|
|
else
|
|
{
|
|
// We don't want this file to get over 65K. If writing this entry
|
|
// will cause the file size to exceed that, then we will delete all
|
|
// of the existing data and start from scratch.
|
|
|
|
DWORD dwLow;
|
|
DWORD dwHigh;
|
|
|
|
dwLow = GetFileSize (hOld, &dwHigh);
|
|
if ((dwHigh != 0) || ((sizeof(DWORD) - dwLow) < CapsSize))
|
|
{
|
|
CloseHandle(hOld);
|
|
bNewFile = TRUE;
|
|
}
|
|
}
|
|
|
|
if (bNewFile)
|
|
{
|
|
// We are creating a new file, which is pretty easy
|
|
|
|
hNew = OpenCacheFile (GENERIC_WRITE, CREATE_ALWAYS, DXCACHEFILENAME, NewFName);
|
|
|
|
if (hNew != INVALID_HANDLE_VALUE)
|
|
{
|
|
NewHeaderSize = sizeof (FDEVICEHEADER);
|
|
WriteFile (hNew, &NewHeaderSize, sizeof(NewHeaderSize), &NumWritten, NULL);
|
|
if (NumWritten == sizeof(NewHeaderSize))
|
|
{
|
|
FDEVICEHEADER DevHeader;
|
|
|
|
DevHeader.VendorId = pDI->VendorId;
|
|
DevHeader.DeviceId = pDI->DeviceId;
|
|
DevHeader.SubSysId = pDI->SubSysId;
|
|
DevHeader.Revision = pDI->Revision;
|
|
DevHeader.FileOffset = sizeof(FDEVICEHEADER) + sizeof(DWORD);
|
|
DevHeader.Size = CapsSize;
|
|
|
|
WriteFile (hNew, &DevHeader, sizeof(DevHeader), &NumWritten, NULL);
|
|
if (NumWritten == sizeof(DevHeader))
|
|
{
|
|
WriteFile (hNew, pCaps, CapsSize, &NumWritten, NULL);
|
|
}
|
|
}
|
|
CloseHandle(hNew);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// The file already exists, so we will create a new file and copy all of the contents
|
|
// from the existing file over.
|
|
|
|
hNew = OpenCacheFile (GENERIC_WRITE, CREATE_ALWAYS, DXTEMPFILENAME, NewFName);
|
|
|
|
if (hNew == INVALID_HANDLE_VALUE)
|
|
{
|
|
goto FileError;
|
|
}
|
|
|
|
ReadFile (hOld, &OldHeaderSize, sizeof(DWORD), &NumRead, NULL);
|
|
if (NumRead < sizeof(DWORD))
|
|
{
|
|
goto FileError;
|
|
}
|
|
pOldHeaderInfo = (FDEVICEHEADER*) MemAlloc(OldHeaderSize);
|
|
if (pOldHeaderInfo == NULL)
|
|
{
|
|
goto FileError;
|
|
}
|
|
ReadFile (hOld, pOldHeaderInfo, OldHeaderSize, &NumRead, NULL);
|
|
if (NumRead < OldHeaderSize)
|
|
{
|
|
goto FileError;
|
|
}
|
|
|
|
// How many entries will exist in the new header?
|
|
|
|
NewEntries = 1;
|
|
for (i = 0; i < OldHeaderSize / sizeof (FDEVICEHEADER); i++)
|
|
{
|
|
if ((pOldHeaderInfo[i].VendorId != pDI->VendorId) ||
|
|
(pOldHeaderInfo[i].DeviceId != pDI->DeviceId) ||
|
|
(pOldHeaderInfo[i].SubSysId != pDI->SubSysId) ||
|
|
(pOldHeaderInfo[i].Revision != pDI->Revision))
|
|
{
|
|
NewEntries++;
|
|
}
|
|
}
|
|
pNewHeaderInfo = (FDEVICEHEADER*) MemAlloc(sizeof(FDEVICEHEADER) * NewEntries);
|
|
if (pNewHeaderInfo == NULL)
|
|
{
|
|
goto FileError;
|
|
}
|
|
|
|
// Fill in the header info for each device and save it to the new file
|
|
|
|
dwOffset = (sizeof(FDEVICEHEADER) * NewEntries) + sizeof(DWORD);
|
|
pNewHeaderInfo[0].VendorId = pDI->VendorId;
|
|
pNewHeaderInfo[0].DeviceId = pDI->DeviceId;
|
|
pNewHeaderInfo[0].SubSysId = pDI->SubSysId;
|
|
pNewHeaderInfo[0].Revision = pDI->Revision;
|
|
pNewHeaderInfo[0].FileOffset = dwOffset;
|
|
pNewHeaderInfo[0].Size = CapsSize;
|
|
dwOffset += CapsSize;
|
|
|
|
NextEntry = 1;
|
|
for (i = 0; i < OldHeaderSize / sizeof (FDEVICEHEADER); i++)
|
|
{
|
|
if ((pOldHeaderInfo[i].VendorId != pDI->VendorId) ||
|
|
(pOldHeaderInfo[i].DeviceId != pDI->DeviceId) ||
|
|
(pOldHeaderInfo[i].SubSysId != pDI->SubSysId) ||
|
|
(pOldHeaderInfo[i].Revision != pDI->Revision))
|
|
{
|
|
pNewHeaderInfo[NextEntry].VendorId = pOldHeaderInfo[i].VendorId;
|
|
pNewHeaderInfo[NextEntry].DeviceId = pOldHeaderInfo[i].DeviceId;
|
|
pNewHeaderInfo[NextEntry].SubSysId = pOldHeaderInfo[i].SubSysId;
|
|
pNewHeaderInfo[NextEntry].Revision = pOldHeaderInfo[i].Revision;
|
|
pNewHeaderInfo[NextEntry].FileOffset = dwOffset;
|
|
pNewHeaderInfo[NextEntry].Size = pOldHeaderInfo[i].Size;
|
|
dwOffset += pOldHeaderInfo[i].Size;
|
|
NextEntry++;
|
|
}
|
|
}
|
|
|
|
NewHeaderSize = sizeof(FDEVICEHEADER) * NewEntries;
|
|
WriteFile (hNew, &NewHeaderSize, sizeof(NewHeaderSize), &NumWritten, NULL);
|
|
if (NumWritten != sizeof(NewHeaderSize))
|
|
{
|
|
goto FileError;
|
|
}
|
|
WriteFile (hNew, pNewHeaderInfo, NewHeaderSize, &NumWritten, NULL);
|
|
if (NumWritten != NewHeaderSize)
|
|
{
|
|
goto FileError;
|
|
}
|
|
|
|
// Write the new device data to the file
|
|
|
|
WriteFile (hNew, pCaps, CapsSize, &NumWritten, NULL);
|
|
if (NumWritten != CapsSize)
|
|
{
|
|
goto FileError;
|
|
}
|
|
|
|
if (NewEntries > 1)
|
|
{
|
|
// Figure out how big the biggest device size is and allocate a buffer
|
|
// to hold it
|
|
|
|
Biggest = 0;
|
|
for (i = 1; i < NewEntries; i++)
|
|
{
|
|
if (pNewHeaderInfo[i].Size > Biggest)
|
|
{
|
|
Biggest = pNewHeaderInfo[i].Size;
|
|
}
|
|
}
|
|
|
|
pBuffer = (BYTE*) MemAlloc(Biggest);
|
|
if (pBuffer == NULL)
|
|
{
|
|
goto FileError;
|
|
}
|
|
|
|
// Now read the device data from the old file and write it to
|
|
// the new on.
|
|
|
|
NextEntry = 0;
|
|
for (i = 0; i < OldHeaderSize / sizeof (FDEVICEHEADER); i++)
|
|
{
|
|
if ((pOldHeaderInfo[i].VendorId != pDI->VendorId) ||
|
|
(pOldHeaderInfo[i].DeviceId != pDI->DeviceId) ||
|
|
(pOldHeaderInfo[i].SubSysId != pDI->SubSysId) ||
|
|
(pOldHeaderInfo[i].Revision != pDI->Revision))
|
|
{
|
|
if (SetFilePointer (hOld, pOldHeaderInfo[i].FileOffset, NULL, FILE_BEGIN) !=
|
|
pOldHeaderInfo[i].FileOffset)
|
|
{
|
|
goto FileError;
|
|
}
|
|
ReadFile (hOld, pBuffer, pOldHeaderInfo[i].Size, &NumRead, NULL);
|
|
if (NumRead < pOldHeaderInfo[i].Size)
|
|
{
|
|
goto FileError;
|
|
}
|
|
WriteFile (hNew, pBuffer, pOldHeaderInfo[i].Size, &NumWritten, NULL);
|
|
if (NumWritten != pOldHeaderInfo[i].Size)
|
|
{
|
|
goto FileError;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// If we made it this far, then everything worked
|
|
|
|
CloseHandle(hNew);
|
|
CloseHandle(hOld);
|
|
DeleteFile(FName);
|
|
MoveFile(NewFName, FName);
|
|
if (pNewHeaderInfo != NULL)
|
|
{
|
|
MemFree(pNewHeaderInfo);
|
|
}
|
|
if (pOldHeaderInfo != NULL)
|
|
{
|
|
MemFree(pOldHeaderInfo);
|
|
}
|
|
if (pBuffer != NULL)
|
|
{
|
|
MemFree(pBuffer);
|
|
}
|
|
return;
|
|
|
|
FileError:
|
|
CloseHandle(hNew);
|
|
CloseHandle(hOld);
|
|
DeleteFile(FName);
|
|
DeleteFile(NewFName);
|
|
|
|
if (pNewHeaderInfo != NULL)
|
|
{
|
|
MemFree(pNewHeaderInfo);
|
|
}
|
|
if (pOldHeaderInfo != NULL)
|
|
{
|
|
MemFree(pOldHeaderInfo);
|
|
}
|
|
if (pBuffer != NULL)
|
|
{
|
|
MemFree(pBuffer);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void RemoveFromCache(D3DADAPTER_IDENTIFIER8* pDI)
|
|
{
|
|
char FName[MAX_PATH + 16];
|
|
char NewFName[MAX_PATH + 16];
|
|
BOOL bNewFile = FALSE;
|
|
HANDLE hOld;
|
|
HANDLE hNew;
|
|
DWORD NewHeaderSize;
|
|
DWORD OldHeaderSize;
|
|
DWORD NumWritten;
|
|
DWORD NumRead;
|
|
FDEVICEHEADER* pOldHeaderInfo = NULL;
|
|
FDEVICEHEADER* pNewHeaderInfo = NULL;
|
|
DWORD dwOffset;
|
|
DWORD i;
|
|
DWORD NewEntries;
|
|
DWORD NextEntry;
|
|
DWORD Biggest;
|
|
BYTE* pBuffer = NULL;
|
|
|
|
// Does the file already exist, or do we need to create a new one?
|
|
|
|
hOld = OpenCacheFile (GENERIC_READ, OPEN_EXISTING, DXCACHEFILENAME, FName);
|
|
|
|
if (hOld == INVALID_HANDLE_VALUE)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ReadFile (hOld, &OldHeaderSize, sizeof(DWORD), &NumRead, NULL);
|
|
if (NumRead < sizeof(DWORD))
|
|
{
|
|
goto FileError;
|
|
}
|
|
if (OldHeaderSize <= sizeof(FDEVICEHEADER))
|
|
{
|
|
// Theres only one entry in the file, so all we need to do
|
|
// is delete it.
|
|
|
|
DeleteFile(FName);
|
|
return;
|
|
}
|
|
|
|
pOldHeaderInfo = (FDEVICEHEADER*) MemAlloc(OldHeaderSize);
|
|
if (pOldHeaderInfo == NULL)
|
|
{
|
|
goto FileError;
|
|
}
|
|
ReadFile (hOld, pOldHeaderInfo, OldHeaderSize, &NumRead, NULL);
|
|
if (NumRead < OldHeaderSize)
|
|
{
|
|
goto FileError;
|
|
}
|
|
|
|
// Create a new file and copy all of the contents from the existing file over.
|
|
|
|
hNew = OpenCacheFile (GENERIC_WRITE, CREATE_ALWAYS, DXTEMPFILENAME, NewFName);
|
|
|
|
if (hNew == INVALID_HANDLE_VALUE)
|
|
{
|
|
goto FileError;
|
|
}
|
|
|
|
// How many entries will exist in the new header?
|
|
|
|
NewEntries = 0;
|
|
for (i = 0; i < OldHeaderSize / sizeof (FDEVICEHEADER); i++)
|
|
{
|
|
if ((pOldHeaderInfo[i].VendorId != pDI->VendorId) ||
|
|
(pOldHeaderInfo[i].DeviceId != pDI->DeviceId) ||
|
|
(pOldHeaderInfo[i].SubSysId != pDI->SubSysId) ||
|
|
(pOldHeaderInfo[i].Revision != pDI->Revision))
|
|
{
|
|
NewEntries++;
|
|
}
|
|
}
|
|
pNewHeaderInfo = (FDEVICEHEADER*) MemAlloc(sizeof(FDEVICEHEADER) * NewEntries);
|
|
if (pNewHeaderInfo == NULL)
|
|
{
|
|
goto FileError;
|
|
}
|
|
|
|
// Fill in the header info for each device and save it to the new file
|
|
|
|
dwOffset = (sizeof(FDEVICEHEADER) * NewEntries) + sizeof(DWORD);
|
|
|
|
NextEntry = 0;
|
|
for (i = 0; i < OldHeaderSize / sizeof (FDEVICEHEADER); i++)
|
|
{
|
|
if ((pOldHeaderInfo[i].VendorId != pDI->VendorId) ||
|
|
(pOldHeaderInfo[i].DeviceId != pDI->DeviceId) ||
|
|
(pOldHeaderInfo[i].SubSysId != pDI->SubSysId) ||
|
|
(pOldHeaderInfo[i].Revision != pDI->Revision))
|
|
{
|
|
pNewHeaderInfo[NextEntry].VendorId = pOldHeaderInfo[i].VendorId;
|
|
pNewHeaderInfo[NextEntry].DeviceId = pOldHeaderInfo[i].DeviceId;
|
|
pNewHeaderInfo[NextEntry].SubSysId = pOldHeaderInfo[i].SubSysId;
|
|
pNewHeaderInfo[NextEntry].Revision = pOldHeaderInfo[i].Revision;
|
|
pNewHeaderInfo[NextEntry].FileOffset = dwOffset;
|
|
pNewHeaderInfo[NextEntry].Size = pOldHeaderInfo[i].Size;
|
|
dwOffset += pOldHeaderInfo[i].Size;
|
|
NextEntry++;
|
|
}
|
|
}
|
|
|
|
NewHeaderSize = sizeof(FDEVICEHEADER) * NewEntries;
|
|
WriteFile (hNew, &NewHeaderSize, sizeof(NewHeaderSize), &NumWritten, NULL);
|
|
if (NumWritten != sizeof(NewHeaderSize))
|
|
{
|
|
goto FileError;
|
|
}
|
|
WriteFile (hNew, pNewHeaderInfo, NewHeaderSize, &NumWritten, NULL);
|
|
if (NumWritten != NewHeaderSize)
|
|
{
|
|
goto FileError;
|
|
}
|
|
|
|
// Figure out how big the biggest device size is and allocate a buffer
|
|
// to hold it
|
|
|
|
Biggest = 0;
|
|
for (i = 0; i < NewEntries; i++)
|
|
{
|
|
if (pNewHeaderInfo[i].Size > Biggest)
|
|
{
|
|
Biggest = pNewHeaderInfo[i].Size;
|
|
}
|
|
}
|
|
|
|
pBuffer = (BYTE*) MemAlloc(Biggest);
|
|
if (pBuffer == NULL)
|
|
{
|
|
goto FileError;
|
|
}
|
|
|
|
// Now read the device data from the old file and write it to
|
|
// the new on.
|
|
|
|
NextEntry = 0;
|
|
for (i = 0; i < OldHeaderSize / sizeof (FDEVICEHEADER); i++)
|
|
{
|
|
if ((pOldHeaderInfo[i].VendorId != pDI->VendorId) ||
|
|
(pOldHeaderInfo[i].DeviceId != pDI->DeviceId) ||
|
|
(pOldHeaderInfo[i].SubSysId != pDI->SubSysId) ||
|
|
(pOldHeaderInfo[i].Revision != pDI->Revision))
|
|
{
|
|
if (SetFilePointer (hOld, pOldHeaderInfo[i].FileOffset, NULL, FILE_BEGIN) !=
|
|
pOldHeaderInfo[i].FileOffset)
|
|
{
|
|
goto FileError;
|
|
}
|
|
ReadFile (hOld, pBuffer, pOldHeaderInfo[i].Size, &NumRead, NULL);
|
|
if (NumRead < pOldHeaderInfo[i].Size)
|
|
{
|
|
goto FileError;
|
|
}
|
|
WriteFile (hNew, pBuffer, pOldHeaderInfo[i].Size, &NumWritten, NULL);
|
|
if (NumWritten != pOldHeaderInfo[i].Size)
|
|
{
|
|
goto FileError;
|
|
}
|
|
}
|
|
}
|
|
|
|
// If we made it this far, then everything worked
|
|
|
|
CloseHandle(hNew);
|
|
CloseHandle(hOld);
|
|
DeleteFile(FName);
|
|
MoveFile(NewFName, FName);
|
|
if (pNewHeaderInfo != NULL)
|
|
{
|
|
MemFree(pNewHeaderInfo);
|
|
}
|
|
if (pOldHeaderInfo != NULL)
|
|
{
|
|
MemFree(pOldHeaderInfo);
|
|
}
|
|
if (pBuffer != NULL)
|
|
{
|
|
MemFree(pBuffer);
|
|
}
|
|
return;
|
|
|
|
FileError:
|
|
CloseHandle(hNew);
|
|
CloseHandle(hOld);
|
|
|
|
if (pNewHeaderInfo != NULL)
|
|
{
|
|
MemFree(pNewHeaderInfo);
|
|
}
|
|
if (pOldHeaderInfo != NULL)
|
|
{
|
|
MemFree(pOldHeaderInfo);
|
|
}
|
|
if (pBuffer != NULL)
|
|
{
|
|
MemFree(pBuffer);
|
|
}
|
|
}
|