📄 devapi.c
字号:
lpdev = (fsdev_t *)lpdev->list.Flink;
}
if (lpdev != (fsdev_t *)&g_DevChain) {
lpFindFileData->dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
*(__int64 *)&lpFindFileData->ftCreationTime = 0;
*(__int64 *)&lpFindFileData->ftLastAccessTime = 0;
*(__int64 *)&lpFindFileData->ftLastWriteTime = 0;
lpFindFileData->nFileSizeHigh = 0;
lpFindFileData->nFileSizeLow = 0;
lpFindFileData->dwOID = 0xffffffff;
wcsncpy(lpFindFileData->cFileName, lpdev->pszLegacyName, ARRAYSIZE(lpFindFileData->cFileName));
bRet = TRUE;
}
}
__except(EXCEPTION_EXECUTE_HANDLER) {
SetLastError(ERROR_INVALID_PARAMETER);
}
LeaveCriticalSection(&g_devcs);
return bRet;
}
// This routine allows the caller to enumerate through the list of
// interfaces associated with a particular device. The dwIndex parameter
// is used to return the Nth interface on the list, so the caller should
// start at 0 and keep going until no more interfaces are available (in which
// case the routine returns FALSE with an error status of ERROR_NO_MORE_ITEMS.
// For each discovered interface, pClass is filled in with the interface GUID,
// pszNameBuf with the name, and lpdwNameBufSize with the number of bytes
// written into pszNameBuf. If the buffer size is too small, the routine returns
// FALSE with an error status of ERROR_INSUFFICIENT_BUFFER but fills in lpdwNameBufSize.
// If the pszNameBuf is NULL and lpdwNameBufSize is not, the routine returns
// its normal status but doesn't fill in a name. Finally, both pszNameBuf and
// lpdwNameBuf size can be NULL, in which case the routine only returns interface class
// information.
BOOL
DM_EnumDeviceInterfaces(HANDLE h, DWORD dwIndex, GUID *pClass, LPWSTR pszNameBuf, LPDWORD lpdwNameBufSize)
{
DWORD dwStatus;
fsdev_t *lpdev = (fsdev_t *) h;
if(pClass == NULL || (pszNameBuf != NULL && lpdwNameBufSize == NULL)) {
dwStatus = ERROR_INVALID_PARAMETER;
goto done;
}
EnterCriticalSection(&g_devcs);
if(!FindDeviceByHandle(lpdev)) {
dwStatus = ERROR_INVALID_HANDLE;
} else {
fsinterface_t *pif = lpdev->pInterfaces;
while(pif != NULL && dwIndex > 0) {
pif = pif->pNext;
dwIndex--;
}
// did we find the interface at the requested index?
if(dwIndex != 0 || pif == NULL) {
dwStatus = ERROR_NO_MORE_ITEMS;
} else {
dwStatus = ERROR_SUCCESS;
__try {
DEBUGCHK(pClass != NULL);
DEBUGCHK(pif->pszName != NULL);
*pClass = pif->guidClass;
if(lpdwNameBufSize != NULL) {
DWORD dwSize = (wcslen(pif->pszName) + 1) * sizeof(pif->pszName[0]);
if(*lpdwNameBufSize < dwSize) {
dwStatus = ERROR_INSUFFICIENT_BUFFER;
}
else if(pszNameBuf != NULL) {
wcscpy(pszNameBuf, pif->pszName);
}
*lpdwNameBufSize = dwSize;
}
}
__except(EXCEPTION_EXECUTE_HANDLER) {
dwStatus = ERROR_INVALID_PARAMETER;
}
}
}
LeaveCriticalSection(&g_devcs);
done:
if(dwStatus != ERROR_SUCCESS) {
SetLastError(dwStatus);
}
return(dwStatus == ERROR_SUCCESS ? TRUE : FALSE);
}
// This routine notifies all devices that have open handles owned
// by a particular process that a PSL event is taking place. The
// PSL event is given by the flags parameter, and currently this
// routine is only called with the DLL_PROCESS_EXITING value.
// Drivers are notified via IOCTL_PSL_NOTIFY that contains a DEVICE_PSL_NOTIFY
// structure in the input buffer.
static void DevPSLNotify (DWORD flags, HPROCESS proc, HTHREAD thread) {
fsopendev_t *fsodev;
int icalls, i;
HANDLE h[20];
HANDLE *ph;
DEVICE_PSL_NOTIFY pslPacket;
EnterCriticalSection(&g_devcs);
fsodev = g_lpOpenDevs;
icalls = 0;
// figure out how many handles this process owns
while (fsodev) {
if (fsodev->hProc == proc)
++icalls;
fsodev = fsodev->nextptr;
}
// Do we need to allocate a handle buffer? We can manage
// up to ARRAYSIZE(h) handles without allocation.
if (icalls < sizeof(h) / sizeof(h[0]))
ph = h;
else {
// allocate an array
ph = (HANDLE *)LocalAlloc (LMEM_FIXED, icalls * sizeof(HANDLE));
if (ph == NULL) { // Run out memory. Do as much as we can
ph = h;
icalls = sizeof(h) / sizeof(h[0]);
};
};
// now copy each device's KHandle -- we'll use this to make the
// IOCTL call
i = 0;
fsodev = g_lpOpenDevs;
while (fsodev && i < icalls) {
if (fsodev->hProc == proc)
ph[i++] = fsodev->KHandle;
fsodev = fsodev->nextptr;
}
LeaveCriticalSection (&g_devcs);
// format the notification packet
pslPacket.dwSize = sizeof(pslPacket);
pslPacket.dwFlags = flags;
pslPacket.hProc = proc;
pslPacket.hThread = thread;
// Now call all the devices using their cached KHandles. If the
// handle is no longer valid the kernel will reject our call.
for (i = 0 ; i < icalls ; ++i)
DeviceIoControl (ph[i], IOCTL_PSL_NOTIFY, (LPVOID)&pslPacket, sizeof(pslPacket), NULL, 0, NULL, NULL);
// free the handle buffer if it was one we allocated
if (ph != h)
LocalFree (ph);
}
// This routine receives PSL notifications for the Device Manager and
// Power Manager PSLs.
void DM_DevProcNotify(DWORD flags, HPROCESS proc, HTHREAD thread) {
switch (flags) {
case DLL_MEMORY_LOW: // memory is getting low
CompactAllHeaps ();
return;
case DLL_PROCESS_EXITING: // process appears to have threads blocked in a PSL call
DevPSLNotify (flags, proc, thread);
break;
case DLL_SYSTEM_STARTED: // all applications launched at system boot time
// Eventually we'll want to signal all drivers that the system has
// initialized. For now do what's necessary.
DevloadPostInit();
break;
}
// notify the power manager
PM_Notify(flags, proc, thread);
return;
}
//
// @func BOOL | CeResyncFilesys | Cause a file system driver to remount a device because of media change.
// @parm HANDLE | hDevice | handle to registered device from RegisterDevice
// @rdesc Returns TRUE for success, FALSE for failure
// @comm CeResyncFilesys is used by a device driver to indicate to its associated file
// system driver that a new volume/media has been inserted. The handle can be retrieved from
// the device's active key in the registry or from the p_hDevice field of the POST_INIT_BUF
// structure passed to the post-initialization IOCTL.
//
//
BOOL DM_CeResyncFilesys(fsdev_t *lpdev)
{
DEVMGR_DEVICE_INFORMATION di;
// get device name information using GetDeviceInformationByDeviceHandle()
memset(&di, 0, sizeof(di));
di.dwSize = sizeof(di);
if(I_GetDeviceInformation(lpdev, &di) != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ERROR,(L"DEVICE: CeResyncFilesys - invalid handle\n"));
return FALSE; // Invalid device handle
}
if ((lpdev->pszLegacyName != NULL) &&
(GetFileAttributesW( L"\\StoreMgr") != -1) &&
(GetFileAttributesW( L"\\StoreMgr") & FILE_ATTRIBUTE_TEMPORARY)) {
WCHAR szFileName[MAX_PATH];
HRESULT hr;
hr = StringCchCopyW(szFileName, ARRAYSIZE(szFileName), L"\\StoreMgr\\");
hr = StringCchCatW(szFileName, ARRAYSIZE(szFileName), lpdev->pszLegacyName);
return(MoveFile( szFileName, szFileName));
}
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -