一个支持操作内存文件操作的类

一个支持操作内存文件操作的类

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;

}

 

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值