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

📄 driverinterface.c

📁 文件驱动加密,功能强大,可产生加密分区,支持AES,MD2,MD4,MD5MD2, MD4, MD5, RIPEMD-128, RIPEMD-160, SHA-1, SHA-224, SHA-256,
💻 C
📖 第 1 页 / 共 2 页
字号:
// Description: 
// By Sarah Dean
// Email: sdean12@sdean12.org
// WWW:   http://www.FreeOTFE.org/
//
// -----------------------------------------------------------------------------
//

#include "DriverInterface.h"
#include "DriverInterfaceCommon.h"
#include "FreeOTFEDebug.h"
#include "FreeOTFElib.h"
#include "FreeOTFE4PDARegistry.h"
#include "FreeOTFEGUIlib.h"
#include "FreeOTFE4PDAAPIConsts.h"

#include "SDUGeneral.h"

#include <stdio.h>  // Needed for wcsncpy(...)
#include <StoreMgr.h>  // Needed for BLOCK_DRIVER_GUID_STRING


// =========================================================================
// Forward declarations...
BOOL _driver_MountDIOC_DLLOption(DIOC_MOUNT* mountDetails, BOOL fullPath);

// =========================================================================
// Obtain driver version ID
// Note: Version ID taken from DLL's version info block
BOOL driver_VersionID(DWORD* versionID)
{
    BOOL retval = FALSE;
    WCHAR* DLLFilename;

    DEBUGOUTGUI(DEBUGLEV_ENTER, (TEXT("driver_VersionID\n")));

    DLLFilename = driver_AllocMainDLLFullFilename(TRUE);
    if (DLLFilename == NULL)
        {
        // Do nothing; retval already set to FALSE
        DEBUGOUTGUI(DEBUGLEV_ERROR, (TEXT("UNABLE TO GET FILENAME FOR MAIN DLL FILENAME")));
        }
    else
        {
        retval = SDUGetVersionInfoShort(DLLFilename, versionID);
        SecZeroAndFreeWCHARMemory(DLLFilename);
        }

    if (!(retval))
        {
        DEBUGOUTGUI(DEBUGLEV_ERROR, (TEXT("FAILED TO GET VERSION ID\n")));
        }
    DEBUGOUTGUI(DEBUGLEV_INFO, (TEXT("Debug level   : %d\n"), FreeOTFEDebugLevel));
    DEBUGOUTGUI(DEBUGLEV_INFO, (TEXT("Driver version: 0x%08x (v%02d.%02d.%04d)\n"),
                                     *versionID, 
                                     (*versionID & 0xFF000000) / 0x00FF0000,
                                     (*versionID & 0x00FF0000) / 0x0000FF00,
                                     (*versionID & 0x0000FFFF)
                                    ));
    DEBUGOUTGUI(DEBUGLEV_EXIT, (TEXT("driver_VersionID\n")));
    return retval;
}


// =========================================================================
BOOL driver_GetMountedCount(int* count)
{
    BOOL retval = FALSE;

    DEBUGOUTGUI(DEBUGLEV_ENTER, (TEXT("driver_GetMountedCount\n")));

    (*count) = RegDetailsGetAllActive(0, NULL);
    retval = ((*count) != -1);

    DEBUGOUTGUI(DEBUGLEV_EXIT, (TEXT("driver_GetMountedCount\n")));
    return retval;
}


// =========================================================================
// Retrieve details of all mounted volumes.
// detailsActiveSize - Size in bytes of detailsActive buffer.                
// detailsActive - Actually an array of REGDETAILS_ACTIVE, this will be
//                 filled in as appropriate
// Note: On failure, the contents of detailsActive are undefined 
// Note: This function will fail if detailsActiveSize doens't reflect the
//       number of mounted volumes
// IMPORTANT: If this function succeeds, it is the caller's responsibility
//            to free of the WCHAR*s, etc in each of the populated
//            REGDETAILS_ACTIVE structures 
BOOL driver_MountedVolumes(
    int detailsActiveSize,  // Size in bytes of detailsActive buffer
    REGDETAILS_ACTIVE *detailsActive  // Actually an array of REGDETAILS_ACTIVE
)
{
    BOOL retval = FALSE;
    int count;
    
    DEBUGOUTGUI(DEBUGLEV_ENTER, (TEXT("driver_MountedVolumes\n")));

    count = RegDetailsGetAllActive(
                                   detailsActiveSize,
                                   detailsActive
                                  );

    retval = (
              (count != -1) &&
              (count == (detailsActiveSize / sizeof(detailsActive[0])))
             );

    if (!(retval))
        {
        DEBUGOUTGUI(DEBUGLEV_ERROR, (TEXT("Unable to get mounted volumes\n")));
        }

    DEBUGOUTGUI(DEBUGLEV_EXIT, (TEXT("driver_MountedVolumes\n")));
    return retval;
}


// =========================================================================
BOOL driver_GetVolumeInfo_DeviceName(
    WCHAR* deviceName, 
    DIOC_DISK_DEVICE_STATUS* volumeDetails
)
{
    BOOL retval = FALSE;
    DWORD bytesReturned;
    HANDLE fileHandle;
    DWORD desiredAccess;
    DWORD fileFlags;

    DEBUGOUTGUI(DEBUGLEV_ENTER, (TEXT("driver_GetVolumeInfo_DeviceName\n")));

    DEBUGOUTGUI(DEBUGLEV_INFO, (TEXT("Trying to open device: %ls...\n"), deviceName));

    desiredAccess = 0; //(GENERIC_READ | GENERIC_WRITE);
    // Note: FILE_ATTRIBUTE_NORMAL only valid if used *alone*
    fileFlags = FILE_ATTRIBUTE_NORMAL;

    fileHandle = CreateFile(
                            deviceName,
                            desiredAccess,  
                            (FILE_SHARE_READ | FILE_SHARE_WRITE),  
                            NULL,
                            OPEN_EXISTING, 
                            fileFlags, 
                            NULL
                           ); 

    if (fileHandle == INVALID_HANDLE_VALUE) 
        {
        DEBUGOUTGUI(DEBUGLEV_ERROR, (TEXT("Unable to open device: %ls\n"), deviceName));
        }
    else
        {
        retval = DeviceIoControl(
                                 fileHandle, 
                                 IOCTL_FREEOTFE_GET_DISK_DEVICE_STATUS, 
                                 NULL, 
                                 0, 
                                 volumeDetails,
                                 sizeof(*volumeDetails),
                                 &bytesReturned,
                                 NULL
                                );

        if (retval)
            {
            DEBUGOUTGUI(DEBUGLEV_INFO, (TEXT("DIOC call OK\n")));
            }
        else
            {
            DEBUGOUTGUI(DEBUGLEV_ERROR, (TEXT("DIOC call failed\n")));
            }

        retval = (bytesReturned == sizeof(*volumeDetails));

        // Slightly paranoid, but...
        if (!(retval))
            {
            SecZeroMemory(volumeDetails, sizeof(*volumeDetails));
            }

        CloseHandle(fileHandle);
        }

    if (retval)
        {
        DEBUGOUTGUI(DEBUGLEV_INFO, (TEXT("Returning TRUE\n")));
        }
    else
        {
        DEBUGOUTGUI(DEBUGLEV_ERROR, (TEXT("Returning FALSE\n")));
        }
    DEBUGOUTGUI(DEBUGLEV_EXIT, (TEXT("driver_GetVolumeInfo_DeviceName\n")));
    return retval;
}


// =========================================================================
BOOL driver_GetVolumeInfo_Mountpoint(
    WCHAR* mountpoint,
    DIOC_DISK_DEVICE_STATUS* volumeDetails
)
{
    BOOL retval = FALSE;
    int cnt;
    REGDETAILS_ACTIVE* mountedDetails;
    BOOL found = FALSE;
    BOOL allOK = FALSE;
    int i;
    int detailsByteSize;

    DEBUGOUTGUI(DEBUGLEV_ENTER, (TEXT("driver_GetVolumeInfo_Mountpoint\n")));

    detailsByteSize = 0;

    // Get details for all volumes
    allOK = driver_GetMountedCount(&cnt);
    if (allOK)
        {
        detailsByteSize = (cnt * sizeof(*mountedDetails)); 
        mountedDetails = malloc(detailsByteSize);
        if (mountedDetails == NULL)
            {
            DEBUGOUTGUI(DEBUGLEV_ERROR, (TEXT("Unable to malloc memory for all volumes mounted\n")));
            allOK = FALSE;
            }
        else
            {
            allOK = driver_MountedVolumes(detailsByteSize, mountedDetails);
            if (!(allOK))
                {
                SecZeroAndFreeMemory(mountedDetails, detailsByteSize);
                mountedDetails = NULL;
                }
            }
        }

    if (allOK) 
        {
        for(i = 0; i < cnt; i++)
            {
            // Identify the volume we're interested in
            if (wcscmp(
                       mountpoint, 
                       mountedDetails[i].Mountpoint
                      ) == 0)
                {
                found = TRUE;

                allOK = driver_GetVolumeInfo_DeviceName(
                                    mountedDetails[i].Name,
                                    volumeDetails
                                   );

                break;
                }
            }
        }

    RegDetailsFreeAllActive(cnt, mountedDetails);
    SecZeroAndFreeMemory(mountedDetails, detailsByteSize);

    retval = (allOK && found);

    DEBUGOUTGUI(DEBUGLEV_EXIT, (TEXT("driver_GetVolumeInfo_Mountpoint\n")));
    return retval;
}


// =========================================================================
// Attempt to mount using the details supplied.
// First we attempt to mount passing the device manager the full path and
// filename to the main DLL in the registry key
// If that fails, we try again, but without the full path to the main DLL
// in which case, Windows Mobile *should* pick up the DLLs from the
// \Windows directory by default
BOOL _driver_MountDIOC(DIOC_MOUNT* mountDetails)
{
    BOOL retval = FALSE;

    DEBUGOUTGUI(DEBUGLEV_ENTER, (TEXT("_driver_MountDIOC\n")));

    retval = _driver_MountDIOC_DLLOption(mountDetails, TRUE);
    if (!(retval))
        {
        retval = _driver_MountDIOC_DLLOption(mountDetails, FALSE);
        }

    DEBUGOUTGUI(DEBUGLEV_EXIT, (TEXT("_driver_MountDIOC\n")));
    return retval;
}


// =========================================================================
// Debug - If the next line is uncommented, then debug messages will be
// displayed to the user during mounting
//#define _DEBUG_ACTIVATEDEVICEEX 1
BOOL _driver_MountDIOC_DLLOption(DIOC_MOUNT* mountDetails, BOOL fullPath)
{
    BOOL retval = FALSE;
    REGDETAILS_BUILTIN regdetailsBuiltin;
    REGDETAILS_PROFILE regdetailsProfile;
    WCHAR* keyBuiltin;    
    HANDLE hActiveDevice = NULL;
    int regDeviceID;
#ifdef _DEBUG_ACTIVATEDEVICEEX
    DWORD errorCode;  // xxx - lplp
#endif
  
    DEBUGOUTGUI(DEBUGLEV_ENTER, (TEXT("_driver_MountDIOC_DLLOption\n")));

    regDeviceID = RegGetNextRegNumber();

    regdetailsBuiltin.Prefix       = DRIVER_PREFIX;
    regdetailsBuiltin.Dll          = driver_AllocMainDLLFullFilename(fullPath);
    regdetailsBuiltin.FriendlyName = DRIVER_FRIENDLYNAME;
    regdetailsBuiltin.Order        = 0;
    regdetailsBuiltin.Ioctl        = 4;
    regdetailsBuiltin.IClass       = BLOCK_DRIVER_GUID_STRING;
    regdetailsBuiltin.Profile      = NULL;  // Determined automatically

    regdetailsProfile.Name         = DRIVER_PROFILE_NAME;
    regdetailsProfile.Folder       = mountDetails->Mountpoint;
    regdetailsProfile.AutoMount    = 1;
    regdetailsProfile.AutoPart     = 1;
    regdetailsProfile.AutoFormat   = 1;
    regdetailsProfile.MountFlags   = 0;

    // Create driver registry entries...
    RegDetailsSetAll(regDeviceID, regdetailsBuiltin, regdetailsProfile);

    // Activate driver...
    RegKeyGenerate(regDeviceID, &keyBuiltin, NULL);
#ifdef _DEBUG_ACTIVATEDEVICEEX
    MsgInfo(NULL, regdetailsBuiltin.Dll);  // xxx - lplp
    MsgInfo(NULL, TEXT("About to activate..."));  // xxx - lplp
    SetLastError(0);  // xxx - lplp
#endif
    hActiveDevice = ActivateDeviceEx(keyBuiltin, NULL, 0, mountDetails);
#ifdef _DEBUG_ACTIVATEDEVICEEX
    // hActiveDevice = NULL;  // xxx - lplp
    errorCode = GetLastError();  // xxx - lplp
#endif
    DEBUGOUTGUI(DEBUGLEV_INFO, (TEXT("ActivateDeviceEx returned handle: 0x%0.8x\n"), hActiveDevice));
    SecZeroAndFreeWCHARMemory(keyBuiltin);

    // On mount failure, purge registry entries created
    if (hActiveDevice == NULL)
        {
#ifdef _DEBUG_ACTIVATEDEVICEEX
        MsgError(NULL, TEXT("Activation failure"));  // xxx - lplp
        MsgErrorDWORD_AsHex(NULL, errorCode);  // xxx - lplp
        SDUDisplayLastError_TextForCode(errorCode);  // xxx - lplp
#endif
        DEBUGOUTGUI(DEBUGLEV_INFO, (TEXT("Mount failed; ActivateDeviceEx returned NULL handle\n")));
        RegDetailsDeleteAllByID(regDeviceID, TRUE);
        }
    else
        {
        DEBUGOUTGUI(DEBUGLEV_INFO, (TEXT("Device activated OK\n")));
        // Pass the active handle received to the driver to store
        if (!(driver_SetUserAppHandle(
                                      (WCHAR*)(mountDetails->Mountpoint),
                                      hActiveDevice
                                     )))
            {
            // Problem!
            // <shrugs> Kill the device...
            DEBUGOUTGUI(DEBUGLEV_ERROR, (TEXT("Unable to pass userspace device handle to device!\n")));
            DeactivateDevice(hActiveDevice);
            hActiveDevice = NULL;
            }

        }

    retval = (hActiveDevice != NULL);

    // Free DLL filename as it's no longer needed
    driver_FreeMainDLLFullFilename(regdetailsBuiltin.Dll);
    regdetailsBuiltin.Dll = NULL;

    DEBUGOUTGUI(DEBUGLEV_EXIT, (TEXT("_driver_MountDIOC_DLLOption\n")));
    return retval;
}


// =========================================================================
// Note: It it the *callers* responsibility to call CloseHandle(...) on the 
//       value returned after use
// Returns INVALID_HANDLE_VALUE on failure
HANDLE driver_GetDeviceHandle(WCHAR* deviceName)
{
    DWORD desiredAccess;
    DWORD fileFlags;
    HANDLE fileHandle;
    WCHAR pathMountpoint[FREEOTFE_MAX_FILENAME_LENGTH];

    DEBUGOUTGUI(DEBUGLEV_ENTER, (TEXT("driver_GetDeviceHandle\n")));

    desiredAccess = 0; //(GENERIC_READ | GENERIC_WRITE);
    // Note: FILE_ATTRIBUTE_NORMAL only valid if used *alone*
    fileFlags = FILE_ATTRIBUTE_NORMAL;

    fileHandle = CreateFile(
                            deviceName,
                            desiredAccess,  
                            (FILE_SHARE_READ | FILE_SHARE_WRITE),  
                            NULL,
                            OPEN_EXISTING, 
                            fileFlags, 
                            NULL
                           ); 

    if (fileHandle == INVALID_HANDLE_VALUE) 
        {
        DEBUGOUTGUI(DEBUGLEV_ERROR, (TEXT("Unable to open device: %ls\n"), deviceName));
        }

    SecZeroMemory(pathMountpoint, sizeof(pathMountpoint));

    DEBUGOUTGUI(DEBUGLEV_EXIT, (TEXT("driver_GetDeviceHandle\n")));
    return fileHandle;
}


// =========================================================================
// Get handle returned by ActivateDeviceEx from device's internal store
HANDLE driver_GetUserAppHandle(WCHAR* mountpoint)
{
    HANDLE retval = NULL;
    DIOC_USER_DEVICE_HANDLE DIOCBuffer;
    DWORD bytesReturned;
    HANDLE fileHandle;
    DIOC_DISK_DEVICE_STATUS volumeDetails;

    DEBUGOUTGUI(DEBUGLEV_ENTER, (TEXT("driver_GetUserAppHandle\n")));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -