📄 fsdalloc.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
/*++
Module Name:
fsdalloc.cpp
Abstract:
This file handles the creation/destruction of all FSDMGR data
structures (ie, FSDs, DSKs, VOLs and HDLs).
--*/
#include "fsdmgrp.h"
/* AllocFSD - Allocate FSD structure and obtain FSD entry points
*
* ENTRY
* hFSD == handle to new FSD
*
* EXIT
* Pointer to internal FSD structure, or NULL if out of memory or
* FSD entry points could not be obtained (use GetLastError if you really
* want to know the answer).
*/
PFSD AllocFSD(HMODULE hFSD, HANDLE hDsk)
{
PFSD pFSD;
WCHAR baseName[MAX_FSD_NAME_SIZE];
pFSD = dlFSDList.pFSDNext;
while (pFSD != (PFSD)&dlFSDList) {
if (CompareFSDs(pFSD->hFSD, hFSD))
break;
pFSD = pFSD->dlFSD.pFSDNext;
}
if (FsdGetProcAddress(hFSD, L"FSD_CreateFileW")) {
/* this guy uses simply FSD_ as a function prefix */
wcscpy(baseName, L"FSD_");
} else {
DWORD cch, i;
WCHAR wsTmp[MAX_PATH];
/* derive the function prefix from the module's name. This is
* a tricky step, since the letter case of the module name must
* match the function prefix within the DLL.
*/
cch = GetModuleFileName(hFSD, wsTmp, ARRAY_SIZE(wsTmp));
if (cch) {
PWSTR pwsTmp = &wsTmp[cch];
while (pwsTmp != wsTmp)
{
pwsTmp--;
if (*pwsTmp == '\\' || *pwsTmp == '/')
{
pwsTmp++;
break;
}
}
i = 0;
while (*pwsTmp && *pwsTmp != '.' && i < ARRAY_SIZE(baseName)-2)
baseName[i++] = *pwsTmp++;
baseName[i] = L'_';
baseName[i+1] = 0;
} else {
return NULL;
}
}
pFSD = (PFSD)LocalAlloc(LPTR, sizeof(FSD));
if (pFSD) {
INITSIG(pFSD, FSD_SIG);
AddListItem((PDLINK)&dlFSDList, (PDLINK)&pFSD->dlFSD);
pFSD->hFSD = hFSD;
pFSD->hDsk = hDsk;
wcscpy( pFSD->wsFSD, baseName);
} else {
DEBUGMSG(ZONE_INIT || ZONE_ERRORS,(DBGTEXT("FSDMGR!AllocFSD: out of memory!\n")));
}
if (pFSD) {
if (!pFSD->pfnMountDisk || !pFSD->pfnUnmountDisk) {
pFSD->pfnMountDisk = (PFNMOUNTDISK)GetFSDProcAddress(pFSD, TEXT("MountDisk"));
pFSD->pfnUnmountDisk = (PFNMOUNTDISK)GetFSDProcAddress(pFSD, TEXT("UnmountDisk"));
}
if (!pFSD->pfnMountDisk || !pFSD->pfnUnmountDisk) {
// CHeck to see if this is a filter
if (!pFSD->pfnHookVolume|| !pFSD->pfnUnhookVolume) {
pFSD->pfnHookVolume = (PFNHOOKVOLUME)GetFSDProcAddress(pFSD, TEXT("HookVolume"));
pFSD->pfnUnhookVolume = (PFNUNHOOKVOLUME)GetFSDProcAddress(pFSD, TEXT("UnhookVolume"));
}
if (!pFSD->pfnHookVolume || !pFSD->pfnUnhookVolume) {
// It doesn't have FSD entrypoints or FILTER entrypoints
DeallocFSD(pFSD);
pFSD = NULL;
}
}
}
if (pFSD) {
if (GetFSDProcArray(pFSD, pFSD->apfnAFS, apfnAFSStubs, apwsAFSAPIs, ARRAY_SIZE(apwsAFSAPIs)) &&
GetFSDProcArray(pFSD, pFSD->apfnFile, apfnFileStubs, apwsFileAPIs, ARRAY_SIZE(apwsFileAPIs)) &&
GetFSDProcArray(pFSD, pFSD->apfnFind, apfnFindStubs, apwsFindAPIs, ARRAY_SIZE(apwsFindAPIs))) {
pFSD->pRefreshVolume = (PREFRESHVOLUME)GetFSDProcAddress(pFSD, L"RefreshVolume");
pFSD->pReadFileScatter = (PREADFILESCATTER)GetFSDProcAddress(pFSD, L"ReadFileScatter");
pFSD->pWriteFileGather = (PWRITEFILEGATHER)GetFSDProcAddress(pFSD, L"WriteFileGather");
pFSD->pfnFormatVolume = (PFNFORMATVOLUME)GetFSDProcAddress(pFSD, L"FormatVolume");
pFSD->pGetVolumeInfo = (PFNGETVOLUMEINFO)GetFSDProcAddress(pFSD, L"GetVolumeInfo");
} else {
DeallocFSD(pFSD);
pFSD = NULL;
}
}
return pFSD;
}
/* DeallocFSD - Deallocate FSD structure
*
* ENTRY
* pFSD -> FSD
*
* EXIT
* TRUE is FSD was successfully deallocated, FALSE if not (eg, if the FSD
* structure still has some DSK structures attached to it).
*/
BOOL DeallocFSD(PFSD pFSD)
{
PREFAST_ASSERT(VALIDSIG(pFSD, FSD_SIG));
RemoveListItem((PDLINK)&pFSD->dlFSD);
LocalFree((HLOCAL)pFSD);
return TRUE;
}
/* AllocDisk - Allocate DSK structure for an FSD
*
* ENTRY
* pFSD -> FSD structure
* pwsDsk -> disk name
* dwFlags == intial disk flags
*
* EXIT
* Pointer to internal DSK structure, or NULL if out of memory
*/
PDSK AllocDisk(PFSD pFSD, PCWSTR pwsDsk, HANDLE hDsk, PDEVICEIOCONTROL pIOControl)
{
DWORD dwFlags = DSK_NONE;
if (pFSD == NULL)
return NULL;
if (hDsk == INVALID_HANDLE_VALUE) {
hDsk = CreateFileW(pwsDsk,
GENERIC_READ | GENERIC_WRITE,
0,
NULL, OPEN_EXISTING, 0, NULL);
if (hDsk != INVALID_HANDLE_VALUE)
dwFlags &= ~DSK_READONLY;
else if (GetLastError() == ERROR_ACCESS_DENIED) {
hDsk = CreateFileW(pwsDsk,
GENERIC_READ,
FILE_SHARE_READ,
NULL, OPEN_EXISTING, 0, NULL);
if (hDsk != INVALID_HANDLE_VALUE)
dwFlags |= DSK_READONLY;
}
pwsDsk = NULL;
}
if (hDsk == INVALID_HANDLE_VALUE) {
DEBUGMSGW(ZONE_INIT || ZONE_ERRORS, (DBGTEXTW("FSDMGR!AllocDisk: CreateFile(%s) failed (%d)\n"), pwsDsk, GetLastError()));
return NULL;
}
PDSK pDsk = (PDSK)LocalAlloc(LPTR, sizeof(DSK));
if (pDsk) {
INITSIG(pDsk, DSK_SIG);
pDsk->pFSD = pFSD;
pDsk->pDeviceIoControl = pIOControl;
pDsk->pVol = NULL;
pDsk->dwFilterVol = 0;
pDsk->hPartition = NULL;
if (pwsDsk) {
wcscpy( pDsk->wsDsk, pwsDsk);
} else {
wcscpy( pDsk->wsDsk, L"");
}
}
if (pDsk) {
pDsk->hDsk = hDsk;
pDsk->dwFlags = dwFlags;
}
return pDsk;
}
/* MarkDisk - Mark a DSK structure with one or more flags
*
* ENTRY
* pDsk -> DSK structure
* dwFlags == one or flags to mark (see DSK_*)
*
* EXIT
* None
*/
void MarkDisk(PDSK pDsk, DWORD dwFlags)
{
PREFAST_ASSERT(VALIDSIG(pDsk, DSK_SIG));
pDsk->dwFlags |= dwFlags;
if ((pDsk->dwFlags & DSK_CLOSED) && (pDsk->hDsk)){
CloseHandle(pDsk->hDsk);
pDsk->hDsk = INVALID_HANDLE_VALUE;
}
}
/* UnmarkDisk - Unmark a DSK structure with one or more flags
*
* ENTRY
* pDsk -> DSK structure
* dwFlags == one or flags to unmark (see DSK_*)
*
* EXIT
* None
*/
void UnmarkDisk(PDSK pDsk, DWORD dwFlags)
{
PREFAST_ASSERT(VALIDSIG(pDsk, DSK_SIG));
pDsk->dwFlags &= ~dwFlags;
}
/* DeallocDisk - Deallocate DSK structure
*
* ENTRY
* pDsk -> DSK structure
*
* EXIT
* TRUE is DSK was successfully deallocated, FALSE if not (eg, if the DSK
* structure still has some VOL structures attached to it).
*/
BOOL DeallocDisk(PDSK pDsk)
{
PREFAST_ASSERT(VALIDSIG(pDsk, DSK_SIG));
if (!pDsk->pVol) {
#ifdef UNDER_CE
if ((pDsk->hDsk != INVALID_HANDLE_VALUE) && (pDsk->hDsk))
CloseHandle(pDsk->hDsk);
#endif
LocalFree((HLOCAL)pDsk);
return TRUE;
}
return FALSE;
}
/* AllocVolume - Allocate VOL structure for a DSK
*
* ENTRY
* pDSK -> DSK structure
* dwVolData == FSD-defined volume data
*
* EXIT
* Pointer to internal VOL structure, or NULL if out of memory
*/
PVOL AllocVolume(PDSK pDsk, DWORD dwVolData)
{
PVOL pVol;
ASSERT(OWNCRITICALSECTION(&csFSD));
if (pDsk == NULL)
return NULL;
pVol = (PVOL)LocalAlloc(LPTR, sizeof(VOL));
if (pVol) {
INITSIG(pVol, VOL_SIG);
InitList((PDLINK)&pVol->dlHdlList);
pDsk->pVol = pVol;
pVol->dwFlags = 0;
pVol->pDsk = pDsk;
pVol->iAFS = INVALID_AFS;
pVol->hThreadExitEvent = NULL;
if (pDsk->pPrevDisk) {
FILTERHOOK fh;
PDSK pTemp = pDsk->pPrevDisk;
while(pTemp) {
fh.hVolume = dwVolData;
fh.cbSize=(sizeof(FILTERHOOK));
fh.pCloseVolume = (PCLOSEVOLUME)pDsk->pFSD->apfnAFS[AFSAPI_CLOSEVOLUME];
fh.pCreateDirectoryW = (PCREATEDIRECTORYW)pDsk->pFSD->apfnAFS[AFSAPI_CREATEDIRECTORYW];
fh.pRemoveDirectoryW = (PREMOVEDIRECTORYW)pDsk->pFSD->apfnAFS[AFSAPI_REMOVEDIRECTORYW];
fh.pGetFileAttributesW = (PGETFILEATTRIBUTESW)pDsk->pFSD->apfnAFS[AFSAPI_GETFILEATTRIBUTESW];
fh.pSetFileAttributesW = (PSETFILEATTRIBUTESW)pDsk->pFSD->apfnAFS[AFSAPI_SETFILEATTRIBUTESW];
fh.pDeleteFileW = (PDELETEFILEW)pDsk->pFSD->apfnAFS[AFSAPI_DELETEFILEW];
fh.pMoveFileW = (PMOVEFILEW)pDsk->pFSD->apfnAFS[AFSAPI_MOVEFILEW];
fh.pDeleteAndRenameFileW = (PDELETEANDRENAMEFILEW)pDsk->pFSD->apfnAFS[AFSAPI_PRESTOCHANGOFILENAME];
fh.pGetDiskFreeSpaceW = (PGETDISKFREESPACEW)pDsk->pFSD->apfnAFS[AFSAPI_GETDISKFREESPACE];
fh.pNotify = (PNOTIFY)pDsk->pFSD->apfnAFS[AFSAPI_NOTIFY];
fh.pRegisterFileSystemFunction = (PREGISTERFILESYSTEMFUNCTION)pDsk->pFSD->apfnAFS[AFSAPI_REGISTERFILESYSTEMFUNCTION];
fh.pFindFirstFileW = (PFINDFIRSTFILEW)pDsk->pFSD->apfnAFS[AFSAPI_FINDFIRSTFILEW];
fh.pCreateFileW = (PCREATEFILEW)pDsk->pFSD->apfnAFS[AFSAPI_CREATEFILEW];
fh.pFsIoControl = (PFSIOCONTROL)pDsk->pFSD->apfnAFS[AFSAPI_FSIOCONTROL];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -