一个支持操作内存文件操作的类
CMemFlash 的核心代码
这段代码的用途请参阅我的一篇文章《无临时文件播放内存中的Flash(*.swf)文件》,支持将内存文件模拟成磁盘文件。本来打算修改完善一下于七月份的时候发布,没想到出了点小意外,电脑的硬盘损坏,花银子买了新硬盘不说,又花更多的银子银子做了数据恢复,终于找回了一些代码,这里奉出,以飨各位,希望可以需要这段代码的给朋友一点帮助。
最好的注释就是代码本身,完整的编译文件可以在www.websamba.com/dust-fly/src/MemFlash.rar下载。(放置文件的是一个免费空间,若不能下载,请从本人上传到CSDN的资源中下载.)
http://download.csdn.net/source/179509
//
// MemoryFile.h
// 通过Hook文件操作函数,把读取磁盘文件的操作转向自己的实现
// 说明:虚拟文件名mlpFileName字符串由CMemoryFile类内部拷贝一份,而内存文件的内存块则使用传入
// 的内存块(重新拷贝一份太浪费内存了)。
#pragma once
class CMemoryFile
{
protected:
// structures
struct MFHANDLE
{
HANDLE hHandle;
LPBYTE pCurPointer;
MFHANDLE *pNext;
};
struct MFFINDHANDLE
{
HANDLE hHandle;
CMemoryFile *pCurMemoryFile;
MFFINDHANDLE *pNext;
};
static MFFINDHANDLE *spFindHandleHead;
MFHANDLE *mpHandleHead;
static CMemoryFile *spHead;
WCHAR* mlpFileName;
LPBYTE mlpFileBuffer;
DWORD mdwFileSizeLow;
DWORD mdwFileSizeHigh;
DWORD mdwFileAttributes;
CMemoryFile *mpNext;
protected:
// static data members
// tCreateFileW record the Ture entrypoint to CreateFileW
static HANDLE (__stdcall *tCreateFileW)(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
static BOOL (__stdcall *tReadFile)(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);
static DWORD (__stdcall *tSetFilePointer)( HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod);
static DWORD (__stdcall *tGetFileSize)( HANDLE hFile, LPDWORD lpFileSizeHigh);
static DWORD (__stdcall *tGetFileAttributesW)(LPCWSTR);
static BOOL (__stdcall *tCloseHandle)(HANDLE hHandle);
static DWORD (__stdcall *tGetFullPathNameW)( LPCWSTR lpFileName, DWORD nBufferLength, LPWSTR lpBuffer, LPWSTR *lpFilePart);
// static BOOL (__stdcall *tGetFileAttributesExW)( LPCWSTR lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId, LPVOID lpFileInformation);
static HANDLE (__stdcall *tFindFirstFileW)( LPCWSTR lpFileName, LPWIN32_FIND_DATAW lpFindFileData);
static BOOL (__stdcall *tFindNextFileW)( HANDLE hFindFile, LPWIN32_FIND_DATAW lpFindFileData);
static BOOL (__stdcall *tFindClose)( HANDLE hFindFile);
// some synchronization objects
static CRITICAL_SECTION sCSFind;
static CRITICAL_SECTION sCSFile;
static CRITICAL_SECTION sCSHandle;
// some addition functions
static CMemoryFile* IsMemoryFile(HANDLE hHandle, MFHANDLE** ppMfHandle);
static CMemoryFile* IsMemoryFile(LPCWSTR lpFileName);
// static method
static HANDLE __stdcall mfCreateFileW(
LPCWSTR lpFileName, // pointer to name of the file
DWORD dwDesiredAccess, // access (read-write) mode
DWORD dwShareMode, // share mode
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security attributes
DWORD dwCreationDisposition, // how to create
DWORD dwFlagsAndAttributes, // file attributes
HANDLE hTemplateFile // handle to file with attributes to copy
);
static BOOL __stdcall mfReadFile(
HANDLE hFile, // handle of file to read
LPVOID lpBuffer, // pointer to buffer that receives data
DWORD nNumberOfBytesToRead, // number of bytes to read
LPDWORD lpNumberOfBytesRead, // pointer to number of bytes read
LPOVERLAPPED lpOverlapped // pointer to structure for data
);
static DWORD __stdcall mfSetFilePointer(
HANDLE hFile, // handle of file
LONG lDistanceToMove, // number of bytes to move file pointer
PLONG lpDistanceToMoveHigh, // pointer to high-order DWORD of distance to move
DWORD dwMoveMethod // how to move
);
static DWORD __stdcall mfGetFileSize(
HANDLE hFile, // handle of file to get size of
LPDWORD lpFileSizeHigh // pointer to high-order word for file size
);
static BOOL __stdcall mfCloseHandle(
HANDLE hObject // handle to object to close
);
static DWORD __stdcall mfGetFileAttributesW(
LPCWSTR lpFileName // handle to object to close
);
static DWORD __stdcall mfGetFullPathNameW(
LPCWSTR lpFileName, // pointer to name of file to find path for
DWORD nBufferLength, // size, in characters, of path buffer
LPWSTR lpBuffer, // pointer to path buffer
LPWSTR *lpFilePart // pointer to filename in path
);
/* static BOOL __stdcall mfGetFileAttributesExW(
LPCWSTR lpFileName, // pointer to string that specifies a file or directory
GET_FILEEX_INFO_LEVELS fInfoLevelId, // value that specifies the type of attribute information to obtain
LPVOID lpFileInformation // pointer to buffer to receive attribute information
);
*/ static HANDLE __stdcall mfFindFirstFileW(
LPCWSTR lpFileName, // pointer to name of file to search for
LPWIN32_FIND_DATAW lpFindFileData // pointer to returned information
);
static BOOL __stdcall mfFindNextFileW(
HANDLE hFindFile, // handle to search
LPWIN32_FIND_DATAW lpFindFileData // pointer to structure for data on found file
);
static BOOL __stdcall mfFindClose(
HANDLE hFindFile // file search handle
);
public:
static BOOL Init(void);
static BOOL Release(void);
CMemoryFile( LPCSTR pFileName, LPVOID lpFileBuffer, int nFileSize, DWORD dwFileAttributes = FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_READONLY);
CMemoryFile( LPCWSTR pFileName, LPVOID lpFileBuffer, int nFileSize, DWORD dwFileAttributes = FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_READONLY);
virtual ~CMemoryFile(void);
private:
// prevent the follow operator and function;
CMemoryFile(CMemoryFile& obj);
CMemoryFile& operator=(CMemoryFile& obj);
public:
// void operator delete(CMemoryFile& obj);
};
//
//
// Core MemoryFile Functionality (MemoryFile.cpp of MemoryFile.lib)
//
// Wrote by SunLine 2007/20/04.
//
// emulate the file action.
//
#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0400)
#define _WIN32_WINNT 0x0400 //
#endif
#if defined(_LIB)
#include <windows.h>
#else
#include "StdAfx.h"
#if defined(_DEBUG)
#pragma comment(lib, "detoursD.lib")
#else
#pragma comment(lib, "detoursR.lib")
#endif //当在VS2005中,这一行应该注释掉
#endif
#include "MemoryFile.h"
#include "detours/detours.h"
HANDLE (__stdcall *CMemoryFile::tCreateFileW)(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) = &::CreateFileW;
BOOL (__stdcall *CMemoryFile::tReadFile)(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped) = &::ReadFile;
DWORD (__stdcall *CMemoryFile::tSetFilePointer)( HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod) = &::SetFilePointer;
DWORD (__stdcall *CMemoryFile::tGetFileSize)( HANDLE hFile, LPDWORD lpFileSizeHigh) = &::GetFileSize;
DWORD (__stdcall *CMemoryFile::tGetFileAttributesW)(LPCWSTR) = &::GetFileAttributesW;
BOOL (__stdcall *CMemoryFile::tCloseHandle)(HANDLE hHandle) = &::CloseHandle;
DWORD (__stdcall *CMemoryFile::tGetFullPathNameW)( LPCWSTR lpFileName, DWORD nBufferLength, LPWSTR lpBuffer, LPWSTR *lpFilePart) = &::GetFullPathNameW;
//BOOL (__stdcall *CMemoryFile::tGetFileAttributesExW)( LPCWSTR lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId, LPVOID lpFileInformation) = &::GetFileAttributesExW;
HANDLE (__stdcall *CMemoryFile::tFindFirstFileW)( LPCWSTR lpFileName, LPWIN32_FIND_DATAW lpFindFileData) = ::FindFirstFileW;
BOOL (__stdcall *CMemoryFile::tFindNextFileW)( HANDLE hFindFile, LPWIN32_FIND_DATAW lpFindFileData) = ::FindNextFileW;
BOOL (__stdcall *CMemoryFile::tFindClose)( HANDLE hFindFile) = ::FindClose;
CRITICAL_SECTION CMemoryFile::sCSFind;
CRITICAL_SECTION CMemoryFile::sCSFile;
CRITICAL_SECTION CMemoryFile::sCSHandle;
CMemoryFile::MFFINDHANDLE* CMemoryFile::spFindHandleHead = NULL;
CMemoryFile* CMemoryFile::spHead = NULL;
//注意:静态数据成员是按照它在CPP文件中定义的顺序初始化的.
HANDLE CMemoryFile::mfCreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, /
LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, /
DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
HANDLE hRet;
CMemoryFile *pMemFile;
if(pMemFile = IsMemoryFile(lpFileName))
{
EnterCriticalSection(&sCSHandle);
MFHANDLE *pHandle = new MFHANDLE;
pHandle->pCurPointer = pMemFile->mlpFileBuffer;
pHandle->pNext = pMemFile->mpHandleHead;
if(pMemFile->mpHandleHead == NULL)
{
pHandle->hHandle = (HANDLE)(~size_t(pMemFile->mlpFileBuffer)&(~WORD(0)<<((sizeof(HANDLE) - sizeof(WORD))*8)));
}
else
{
pHandle->hHandle = (HANDLE)((LPBYTE)pMemFile->mpHandleHead->hHandle + 1);
}
LONG lRet = InterlockedExchange(&(LONG&)pMemFile->mpHandleHead, (LONG&)pHandle);
hRet = pHandle->hHandle;
LeaveCriticalSection(&sCSHandle);
}
else
{
hRet = tCreateFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
}
return hRet;
}
BOOL CMemoryFile::mfReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, /
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped)
{
BOOL bRet;
MFHANDLE *pMfHandle;
CMemoryFile *pMemFile;
if(pMemFile = IsMemoryFile(hFile, &pMfHandle))
{
LPBYTE lpFileEnd = LPBYTE(pMemFile->mlpFileBuffer + pMemFile->mdwFileSizeLow);
DWORD dwNumOfByteRead = 0;
if(pMfHandle->pCurPointer >= lpFileEnd)
{
*lpNumberOfBytesRead = 0;
}
else if((pMfHandle->pCurPointer + nNumberOfBytesToRead) < lpFileEnd)
{
dwNumOfByteRead = nNumberOfBytesToRead;
}
else
{
dwNumOfByteRead = (DWORD)(lpFileEnd - pMfHandle->pCurPointer);
}
memcpy(lpBuffer, pMfHandle->pCurPointer, dwNumOfByteRead);
pMfHandle->pCurPointer = pMfHandle->pCurPointer + dwNumOfByteRead;
*lpNumberOfBytesRead = dwNumOfByteRead;
bRet = TRUE;
}
else
{
bRet = tReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
}
return bRet;
}
DWORD CMemoryFile::mfGetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
{
DWORD dwRet;
MFHANDLE *pMfHandle;
CMemoryFile *pMemFile = IsMemoryFile(hFile, &pMfHandle);
if(pMemFile)
{
*lpFileSizeHigh = pMemFile->mdwFileSizeHigh;
dwRet = pMemFile->mdwFileSizeLow;
}
else
{
dwRet = tGetFileSize(hFile, lpFileSizeHigh);
}
return dwRet;
}
DWORD CMemoryFile::mfSetFilePointer(HANDLE hFile, LONG lDistanceToMove, /
PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod)
{
DWORD dwRet;
MFHANDLE *pMfHandle;
CMemoryFile *pMemFile;
if(pMemFile = IsMemoryFile(hFile, &pMfHandle))
{
switch(dwMoveMethod)
{
case FILE_BEGIN:
pMfHandle->pCurPointer = pMemFile->mlpFileBuffer + lDistanceToMove;
break;
case FILE_CURRENT:
pMfHandle->pCurPointer = pMfHandle->pCurPointer + lDistanceToMove;
break;
case FILE_END:
pMfHandle->pCurPointer = pMemFile->mlpFileBuffer + pMemFile->mdwFileSizeLow + lDistanceToMove;
break;
}
if(LPBYTE(pMfHandle->pCurPointer) < LPBYTE(pMemFile->mlpFileBuffer))
{
dwRet = lDistanceToMove - DWORD(pMemFile->mlpFileBuffer - pMfHandle->pCurPointer);
pMfHandle->pCurPointer = pMemFile->mlpFileBuffer;
}
if(pMfHandle->pCurPointer < (pMemFile->mlpFileBuffer + pMemFile->mdwFileSizeLow))
{
dwRet = lDistanceToMove - DWORD(pMfHandle->pCurPointer - pMemFile->mlpFileBuffer);
pMfHandle->pCurPointer = LPBYTE(pMemFile->mlpFileBuffer) + pMemFile->mdwFileSizeLow;
}
}
else
{
dwRet = tSetFilePointer(hFile, lDistanceToMove, lpDistanceToMoveHigh, dwMoveMethod);
}
return dwRet;
}
DWORD CMemoryFile::mfGetFileAttributesW(LPCWSTR lpFileName)
{
DWORD dwRet;
CMemoryFile *pMemFile;
if(pMemFile = IsMemoryFile(lpFileName))
{
dwRet = pMemFile->mdwFileAttributes;
}
else
{
dwRet = tGetFileAttributesW(lpFileName);
}
return dwRet;
}
BOOL CMemoryFile::mfCloseHandle(HANDLE hObject)
{
CMemoryFile* pMemFile;
MFHANDLE *pPreHandle = NULL;
MFHANDLE *pHandle;
EnterCriticalSection(&sCSHandle);
for(pMemFile = spHead; pMemFile != NULL; pMemFile = pMemFile->mpNext)
{
for(pHandle = pMemFile->mpHandleHead; pHandle != NULL; pPreHandle = pHandle, pHandle = pHandle->pNext)
{
if(pHandle->hHandle == hObject)
{
if(pPreHandle)
{
//pPreHandle->pNext = pMemFile->mpNext;
::InterlockedExchange(&(LONG&)pPreHandle->pNext, (LONG&)pMemFile->mpNext);
}
else
{
//pMemFile->mpHandleHead = NULL;
::InterlockedExchange(&(LONG&)pMemFile->mpHandleHead, NULL);
}
delete pHandle;
LeaveCriticalSection(&sCSHandle);
return TRUE;
}
}
}
LeaveCriticalSection(&sCSHandle);
return tCloseHandle(hObject);
}
DWORD CMemoryFile::mfGetFullPathNameW(LPCWSTR lpFileName, DWORD nBufferLength, LPWSTR lpBuffer, LPWSTR *lpFilePart)
{
DWORD dwRet;
CMemoryFile *pMemFile = IsMemoryFile(lpFileName);
if(pMemFile)
{
int nStrLen = lstrlenW(lpFileName);
LPWSTR pStr;
if(nBufferLength < (nStrLen + 1) * sizeof(WCHAR))
return 0;
lstrcpyW((LPWSTR)lpBuffer, lpFileName);
for(pStr = lpBuffer + nStrLen; (*pStr != L'//') && (pStr >= lpBuffer); pStr--);
*lpFilePart = ++pStr;
dwRet = nStrLen;
}
else
{
dwRet = tGetFullPathNameW(lpFileName, nBufferLength, lpBuffer, lpFilePart);
}
return dwRet;
}
//BOOL CMemoryFile::mfGetFileAttributesExW(LPCWSTR lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId, LPVOID lpFileInformation)
//{
// //CMemoryFile *pMemoryFile = IsMemoryFile(lpFileName);
// //if(pMemoryFile)
// //{
// // return 0x21;
// // //return pMemoryFile->mdwFileAttributes;
// //}
// BOOL bRet = tGetFileAttributesExW(lpFileName, fInfoLevelId, lpFileInformation);
// return bRet;
//}
HANDLE CMemoryFile::mfFindFirstFileW(LPCWSTR lpFileName, LPWIN32_FIND_DATAW lpFindFileData)
{
HANDLE hRet;
CMemoryFile *pMemFile;
if(pMemFile = IsMemoryFile(lpFileName))
{
MFFINDHANDLE *pFindHandle = new MFFINDHANDLE;
EnterCriticalSection(&sCSFind);
//pFindHandle->hHandle = pMemFile->mlpFileBuffer;
pFindHandle->pCurMemoryFile = pMemFile;
pFindHandle->pNext = spFindHandleHead;
if(spFindHandleHead == NULL)
{
pFindHandle->hHandle = (HANDLE)(~size_t(&spFindHandleHead)&(~WORD(0)<<((sizeof(HANDLE) - sizeof(WORD))*8)));//用高位作为内存文件间的标志,而低位用来标识不同的句柄
}
else
{
pFindHandle->hHandle = (HANDLE)(PBYTE(spFindHandleHead->hHandle) + 1);
}
LONG lRet = InterlockedExchange(&(LONG&)spFindHandleHead, (LONG&)pFindHandle);
hRet = pFindHandle->hHandle;
LeaveCriticalSection(&sCSFind);
}
else
{
hRet = tFindFirstFileW(lpFileName, lpFindFileData);
}
return hRet;
}
BOOL CMemoryFile::mfFindNextFileW(HANDLE hFindFile, LPWIN32_FIND_DATAW lpFindFileData)
{
BOOL bRet;
CMemoryFile* pMemFile;
MFFINDHANDLE *pHandle;
EnterCriticalSection(&sCSFind);
for(pMemFile = spHead; pMemFile != NULL; pMemFile = pMemFile->mpNext)
{
for(pHandle = spFindHandleHead; pHandle != NULL; pHandle = pHandle->pNext)
{
if(pHandle->hHandle == hFindFile)
{
lstrcpyW(lpFindFileData->cFileName, pMemFile->mlpFileName);
lpFindFileData->nFileSizeHigh = 0;
lpFindFileData->nFileSizeLow = pMemFile->mdwFileSizeLow;
LeaveCriticalSection(&sCSFind);
return TRUE;
}
}
}
LeaveCriticalSection(&sCSFind);
bRet = tFindNextFileW(hFindFile, lpFindFileData);
return bRet;
}
BOOL CMemoryFile::mfFindClose(HANDLE hFindFile)
{
BOOL bRet;
CMemoryFile* pMemFile;
MFFINDHANDLE *pPreHandle = NULL;
MFFINDHANDLE *pHandle;
EnterCriticalSection(&sCSFind);
for(pMemFile = spHead; pMemFile != NULL; pMemFile = pMemFile->mpNext)
{
for(pHandle = spFindHandleHead; pHandle != NULL; pPreHandle = pHandle, pHandle = pHandle->pNext)
{
if(pHandle->hHandle == hFindFile)
{
if(pPreHandle)
{
pPreHandle->pNext = pHandle->pNext;
::InterlockedExchange(&(LONG&)pPreHandle->pNext, (LONG&)pMemFile->mpNext);
}
else
{
spFindHandleHead = NULL;
::InterlockedExchange(&(LONG&)spFindHandleHead,NULL);
}
delete pHandle;
LeaveCriticalSection(&sCSFind);
return TRUE;
}
}
}
LeaveCriticalSection(&sCSFind);
bRet = tFindClose(hFindFile);
return bRet;
}
CMemoryFile::CMemoryFile( LPCSTR pFileName, LPVOID lpFileBuffer, int nFileSize, DWORD dwFileAttributes)
{
if( (lstrlenA(pFileName) == 0) || (lpFileBuffer == NULL ))
throw -1;
if(::IsBadReadPtr(lpFileBuffer, nFileSize))
{
throw -2;
}
int nRet;
LONG lRet;
int nLen = (int)(2 * lstrlenA(pFileName));
LPWSTR lpwFileName = new WCHAR[nLen];
nRet = MultiByteToWideChar(CP_THREAD_ACP, MB_ERR_INVALID_CHARS, pFileName, -1, lpwFileName, nLen);
if(!nRet)
{
delete[] lpwFileName;
throw GetLastError();
}
if(IsMemoryFile(lpwFileName))
{
delete[] lpwFileName;
throw -2;
}
mdwFileAttributes = dwFileAttributes;
mdwFileSizeHigh = 0;
mdwFileSizeLow = nFileSize;
mlpFileBuffer = (LPBYTE)lpFileBuffer;
mlpFileName = lpwFileName;
mpHandleHead = NULL;
CMemoryFile *tp = this;
// 使用TryEnterCriticalSection是为了兼容编译为静态库时,在用new方法初次创建CMemoryFile对象时
// 静态初始化成员memfileInit还没有初始化sCSFile,此构造函数执行完毕后才构造memfileInit,完成初始化
if(TryEnterCriticalSection(&sCSFile))
{
mpNext = spHead;
lRet = InterlockedExchange(&(LONG&)spHead, (LONG&)tp);
LeaveCriticalSection(&sCSFile);
}
else
{
if(spHead == NULL)
{
mpNext = spHead;
lRet = InterlockedExchange(&(LONG&)spHead, (LONG&)tp);
}
else
{
throw -1;
}
}
}
CMemoryFile::CMemoryFile( LPCWSTR pFileName, LPVOID lpFileBuffer, int nFileSize, DWORD dwFileAttributes)
{
if( (lstrlenW(pFileName) == 0) || (lpFileBuffer == NULL ))
{
throw -1;
}
if(::IsBadReadPtr(lpFileBuffer, nFileSize))
{
throw -2;
}
if(IsMemoryFile(pFileName))
{
throw -2;
}
LONG lRet;
mdwFileAttributes = dwFileAttributes;
mdwFileSizeHigh = 0;
mdwFileSizeLow = nFileSize;
mlpFileBuffer = (LPBYTE)lpFileBuffer;
LPWSTR pwFileName = new WCHAR[lstrlenW(pFileName) + 1];
lstrcpyW(pwFileName, pFileName);
CMemoryFile *tp = this;
if(TryEnterCriticalSection(&sCSFile))
{
mpNext = spHead;
lRet = InterlockedExchange(&(LONG&)spHead, (LONG&)tp);
LeaveCriticalSection(&sCSFile);
}
else
{
if(spHead == NULL)
{
mpNext = spHead;
lRet = InterlockedExchange(&(LONG&)spHead, (LONG&)tp);
}
else
{
throw -1;
}
}
}
CMemoryFile::~CMemoryFile(void)
{
EnterCriticalSection(&sCSHandle);
if(mpHandleHead == NULL)
{
delete[] mlpFileName;
mlpFileName = NULL;
}
LeaveCriticalSection(&sCSHandle);
CMemoryFile *pMemFile, *pPreMemFile;
EnterCriticalSection(&sCSFile);
for(pPreMemFile = NULL, pMemFile = spHead; pMemFile != NULL; pPreMemFile = pMemFile, pMemFile = pMemFile->mpNext)
{
if(pPreMemFile != NULL)
{
//pPreMemFile->pNext = pMemFile->pNext;
::InterlockedExchange(&(LONG&)pPreMemFile->mpNext, (LONG&)pMemFile->mpNext);
}
else
{
//spHead = NULL;
::InterlockedExchange(&(LONG&)spHead, (LONG&)pMemFile->mpNext);
}
}
LeaveCriticalSection(&sCSFile);
}
CMemoryFile* CMemoryFile::IsMemoryFile(HANDLE hHandle, MFHANDLE** ppMfHandle)
{
CMemoryFile* pMemFile;
MFHANDLE *pHandle;
for(pMemFile = spHead; pMemFile != NULL; pMemFile = pMemFile->mpNext)
{
for(pHandle = pMemFile->mpHandleHead; pHandle != NULL; pHandle = pHandle->pNext)
{
if(pHandle->hHandle == hHandle)
{
*ppMfHandle = pHandle;
return pMemFile;
}
}
}
ppMfHandle = NULL;
return NULL;
}
CMemoryFile* CMemoryFile::IsMemoryFile(LPCWSTR lpFileName)
{
CMemoryFile* p;
for(p = spHead; (p != NULL) && (lstrcmpW(p->mlpFileName, lpFileName) != 0); p = p->mpNext);
return p;
}
//CMemoryFile::CMemoryFile(CMemoryFile& obj)
//{
// int nLen = lstrlenW(obj.lpFileName) + 2;
// lpFileName = new WCHAR[nLen];
// lstrcpyW(lpFileName, obj.lpFileName);
//
// lpFileBuffer = obj.lpFileBuffer;
lpCurPoint = lpFileBuffer;
// dwFileSizeLow = obj.dwFileSizeLow;
// dwFileSizeHigh = obj.dwFileSizeHigh;
// dwFileAttributes = obj.dwFileAttributes;
hHandle = obj.hHandle;
lpCurPoint = lpFileBuffer;
// pNext = NULL;
//}
BOOL CMemoryFile::Release(void)
{
if(spHead != NULL)
return FALSE;
LONG lRet = TRUE;
lRet = DetourTransactionBegin();
lRet |= DetourUpdateThread(GetCurrentThread());
lRet |= DetourDetach(&(PVOID&)tFindClose, mfFindClose);
lRet |= DetourDetach(&(PVOID&)tFindNextFileW, mfFindNextFileW);
lRet |= DetourDetach(&(PVOID&)tFindFirstFileW, mfFindFirstFileW);
//lRet |= DetourDetach(&(PVOID&)tGetFileAttributesExW, mfGetFileAttributesExW);
lRet |= DetourDetach(&(PVOID&)tGetFullPathNameW, mfGetFullPathNameW);
lRet |= DetourDetach(&(PVOID&)tCloseHandle, mfCloseHandle);
lRet |= DetourDetach(&(PVOID&)tGetFileAttributesW, mfGetFileAttributesW);
lRet |= DetourDetach(&(PVOID&)tGetFileSize, mfGetFileSize);
lRet |= DetourDetach(&(PVOID&)tSetFilePointer, mfSetFilePointer);
lRet |= DetourDetach(&(PVOID&)tReadFile, mfReadFile);
lRet |= DetourDetach(&(PVOID&)tCreateFileW, mfCreateFileW);
lRet |= DetourTransactionCommit();
DeleteCriticalSection(&sCSHandle);
DeleteCriticalSection(&sCSFile);
DeleteCriticalSection(&sCSFind);
return !lRet;
}
CMemoryFile& CMemoryFile::operator=(CMemoryFile& obj)
{
//TODO: insert return statement here
return obj;
}
//void CMemoryFile::operator delete(CMemoryFile& obj)
//{
// if((mpHandleHead != NULL ) || (spFindHandleHead != NULL))
// throw -1;
// delete []mlpFileName;
//}
BOOL CMemoryFile::Init(void)
{
LONG lRet = 0;
InitializeCriticalSection(&sCSFind);
InitializeCriticalSection(&sCSFile);
InitializeCriticalSection(&sCSHandle);
lRet |= DetourTransactionBegin();
lRet |= DetourUpdateThread(GetCurrentThread());
lRet |= DetourAttach(&(PVOID&)tCreateFileW, mfCreateFileW);
lRet |= DetourAttach(&(PVOID&)tReadFile, mfReadFile);
lRet |= DetourAttach(&(PVOID&)tSetFilePointer, mfSetFilePointer);
lRet |= DetourAttach(&(PVOID&)tGetFileSize, mfGetFileSize);
lRet |= DetourAttach(&(PVOID&)tGetFileAttributesW, mfGetFileAttributesW);
lRet |= DetourAttach(&(PVOID&)tCloseHandle, mfCloseHandle);
lRet |= DetourAttach(&(PVOID&)tGetFullPathNameW, mfGetFullPathNameW);
//lRet |= DetourAttach(&(PVOID&)tGetFileAttributesExW, mfGetFileAttributesExW);
lRet |= DetourAttach(&(PVOID&)tFindFirstFileW, mfFindFirstFileW);
lRet |= DetourAttach(&(PVOID&)tFindNextFileW, mfFindNextFileW);
lRet |= DetourAttach(&(PVOID&)tFindClose, mfFindClose);
lRet |= DetourTransactionCommit();
return !lRet;
}