⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 devapi.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 2 页
字号:
            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 + -