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

📄 diskio.c

📁 wince ramdisk drivers
💻 C
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name:  

    diskio.c

Abstract:  

    Windows CE RAM disk driver.

--*/
#include "ramdisk.h"

#define REG_PROFILE_KEY     TEXT("Profile")
#define DEFAULT_PROFILE     TEXT("Default")


//------------------------------------------------------------------------------
//
// Function to open the driver key specified by the active key
//
// The caller is responsible for closing the returned HKEY
//
//------------------------------------------------------------------------------
HKEY
OpenDriverKey(
    LPTSTR ActiveKey
    )
{
    TCHAR DevKey[256];
    HKEY hDevKey;
    HKEY hActive;
    DWORD ValType;
    DWORD ValLen;
    DWORD status;

    //
    // Get the device key from active device registry key
    //
    status = RegOpenKeyEx(
                HKEY_LOCAL_MACHINE,
                ActiveKey,
                0,
                0,
                &hActive);
    if (status) {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR,
            (TEXT("RAM:OpenDriverKey RegOpenKeyEx(HLM\\%s) returned %d!!!\r\n"),
                  ActiveKey, status));
        return NULL;
    }

    hDevKey = NULL;

    ValLen = sizeof(DevKey);
    status = RegQueryValueEx(
                hActive,
                DEVLOAD_DEVKEY_VALNAME,
                NULL,
                &ValType,
                (PUCHAR)DevKey,
                &ValLen);
    if (status != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR,
            (TEXT("RAM:OpenDriverKey - RegQueryValueEx(%s) returned %d\r\n"),
                  DEVLOAD_DEVKEY_VALNAME, status));
        goto odk_fail;
    }

    //
    // Get the geometry values from the device key
    //
    status = RegOpenKeyEx(
                HKEY_LOCAL_MACHINE,
                DevKey,
                0,
                0,
                &hDevKey);
    if (status) {
        hDevKey = NULL;
        DEBUGMSG(ZONE_INIT|ZONE_ERROR,
            (TEXT("RAM:OpenDriverKey RegOpenKeyEx - DevKey(HLM\\%s) returned %d!!!\r\n"),
                  DevKey, status));
    }

odk_fail:
    RegCloseKey(hActive);
    return hDevKey;
}   // OpenDriverKey



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
DWORD
GetDiskSize(
    PDISK pDisk
    )
{
    HKEY DriverKey;
    DWORD ValType;
    DWORD status;
    DWORD dwValue;
    DWORD dwBytes;

    DEBUGMSG(ZONE_INIT|ZONE_ERROR, (TEXT("RAM:GetDiskSize - %s\r\n"), pDisk->d_ActivePath));
    
    DriverKey = OpenDriverKey(pDisk->d_ActivePath);
    if (DriverKey) {
        dwBytes = sizeof(dwValue);
        status = RegQueryValueEx(DriverKey, TEXT("Size"), NULL, &ValType,
                    (PUCHAR)&dwValue, &dwBytes);
        
        if (status != ERROR_SUCCESS) {
            DEBUGMSG(ZONE_INIT|ZONE_ERROR,
                (TEXT("RAM:GetDiskSize - RegQueryValueEx(Size) returned %d\r\n"),
                      status));
            dwValue = RD_SIZE;
        } else {
            DEBUGMSG(ZONE_INIT,(TEXT("RAM:GetDiskSize - %d\r\n"), dwValue));
        }
        RegCloseKey(DriverKey);
    } else {
        dwValue = RD_SIZE;
    }
    
    return dwValue;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
DWORD
GetDiskAddress(
    PDISK pDisk
    )
{
    HKEY DriverKey;
    DWORD ValType;
    DWORD status;
    DWORD dwValue;
    DWORD dwBytes;

    DEBUGMSG(ZONE_INIT|ZONE_ERROR, (TEXT("RAM:GetDiskAddress - %s\r\n"), pDisk->d_ActivePath));
    
    DriverKey = OpenDriverKey(pDisk->d_ActivePath);
    if (DriverKey) {
        dwBytes = sizeof(dwValue);
        status = RegQueryValueEx(DriverKey, TEXT("Address"), NULL, &ValType,
                    (PUCHAR)&dwValue, &dwBytes);
        
        if (status != ERROR_SUCCESS) {
            DEBUGMSG(ZONE_INIT|ZONE_ERROR,
                (TEXT("RAM:GetDiskAddress - RegQueryValueEx(Size) returned %d\r\n"),
                      status));
            dwValue = 0;
        } else {
            DEBUGMSG(ZONE_INIT,(TEXT("RAM:GetDiskAddress - %d\r\n"), dwValue));
        }
        RegCloseKey(DriverKey);
    } else {
        dwValue = 0;
    }
    
    return dwValue;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL GetDeviceInfo(PDISK pDisk, PSTORAGEDEVICEINFO pInfo)
{
    BOOL fRet = FALSE;
    HKEY hKeyDriver;
    DWORD dwBytes;
    DWORD dwStatus;
    DWORD dwValType;

    if(pDisk && pInfo)
    {
        _tcsncpy(pInfo->szProfile, DEFAULT_PROFILE, PROFILENAMESIZE);
        __try
        {
            hKeyDriver = OpenDriverKey(pDisk->d_ActivePath);
            if(hKeyDriver)
            {
                // read the profile string from the active reg key if it exists
                dwBytes = sizeof(pInfo->szProfile);
                dwStatus = RegQueryValueEx(hKeyDriver, REG_PROFILE_KEY, NULL, &dwValType,
                    (PBYTE)&pInfo->szProfile, &dwBytes);
                
                // if this fails, szProfile will contain the default string
            }

            // set our class, type, and flags
            pInfo->dwDeviceClass = STORAGE_DEVICE_CLASS_BLOCK;
            pInfo->dwDeviceType = STORAGE_DEVICE_TYPE_UNKNOWN;
            pInfo->dwDeviceFlags = STORAGE_DEVICE_FLAG_READWRITE;
            fRet = TRUE;
        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {
            SetLastError(ERROR_INVALID_PARAMETER);
            fRet = FALSE;
        }
    }
    return fRet;
}

//------------------------------------------------------------------------------
//
// Function to retrieve the folder name value from the driver key. The folder name is
// used by FATFS to name this disk volume.
//
//------------------------------------------------------------------------------
BOOL
GetFolderName(
    PDISK pDisk,
    LPWSTR FolderName,
    DWORD cBytes,
    DWORD * pcBytes
    )
{
    HKEY DriverKey;
    DWORD ValType;
    DWORD status;

    DriverKey = OpenDriverKey(pDisk->d_ActivePath);
    if (DriverKey) {
        *pcBytes = cBytes;
        status = RegQueryValueEx(
                    DriverKey,
                    TEXT("Folder"),
                    NULL,
                    &ValType,
                    (PUCHAR)FolderName,
                    pcBytes);
        if (status != ERROR_SUCCESS) {
            DEBUGMSG(ZONE_INIT|ZONE_ERROR,
                (TEXT("RAM:GetFolderName - RegQueryValueEx(Folder) returned %d\r\n"),
                      status));
            *pcBytes = 0;
        } else {
            DEBUGMSG(ZONE_INIT|ZONE_ERROR,
                (TEXT("RAM:GetFolderName - FolderName = %s, length = %d\r\n"),
                 FolderName, *pcBytes));
           *pcBytes += sizeof(WCHAR); // account for terminating 0.
        }
        RegCloseKey(DriverKey);
        if (status || (*pcBytes == 0)) {
            // Use default
            return FALSE; 
        }
        return TRUE;
    }
    
    return FALSE;
}



//------------------------------------------------------------------------------
//
// CloseDisk - free all resources associated with the specified disk
//
//------------------------------------------------------------------------------
VOID
CloseDisk(
    PDISK pDisk
    )
{
    PDISK pd;

    DEBUGMSG(ZONE_IO, (TEXT("RAMDISK:CloseDisk closing 0x%x\r\n"), pDisk));

    //
    // Remove it from the global list of disks
    //
    EnterCriticalSection(&v_DiskCrit);
    if (pDisk == v_DiskList) {
        v_DiskList = pDisk->d_next;
    } else {
        pd = v_DiskList;
        while (pd->d_next != NULL) {
            if (pd->d_next == pDisk) {
                pd->d_next = pDisk->d_next;
                break;
            }
            pd = pd->d_next;
        }
    }
    LeaveCriticalSection(&v_DiskCrit);

    DEBUGMSG(ZONE_IO, (TEXT("RAMDISK:CloseDisk - freeing PCMCIA resources\r\n")));

    //
    // Try to ensure this is the only thread holding the disk crit sec
    //
    Sleep(50);
    EnterCriticalSection(&(pDisk->d_DiskCardCrit));
    LeaveCriticalSection(&(pDisk->d_DiskCardCrit));
    DeleteCriticalSection(&(pDisk->d_DiskCardCrit));
    LocalFree(pDisk->pbRAM);
    LocalFree(pDisk);
    DEBUGMSG(ZONE_IO, (TEXT("RAMDISK:CloseDisk done with 0x%x\r\n"), pDisk));
}



//------------------------------------------------------------------------------
//
// DoDiskIO - Perform requested I/O.
//            This function is called from DSK_IOControl.
//
// Requests are serialized using the disk's critical section.
//
//------------------------------------------------------------------------------
DWORD
DoDiskIO(
    PDISK pDisk,
    DWORD Opcode,
    PSG_REQ pSgr
    )
{
    DWORD status = ERROR_SUCCESS;
    DWORD num_sg;
    DWORD curr_byte;
    DWORD bytes_this_sg;
    PSG_BUF pSg;
    PUCHAR pBuf;
    volatile PUCHAR pCard;

    pSgr->sr_status = ERROR_IO_PENDING;

    if (pSgr->sr_num_sg > MAX_SG_BUF) {
        status = ERROR_INVALID_PARAMETER;
        goto ddi_exit;
    }

    //
    // Make sure request doesn't exceed the disk
    //
    if ((pSgr->sr_start + pSgr->sr_num_sec - 1) > pDisk->d_DiskInfo.di_total_sectors) {
        status = ERROR_SECTOR_NOT_FOUND;
        goto ddi_exit;
    }
    status = ERROR_SUCCESS;
    curr_byte = pSgr->sr_start * BYTES_PER_SECTOR;

    num_sg = pSgr->sr_num_sg;
    pSg = &(pSgr->sr_sglist[0]);
    bytes_this_sg = pSg->sb_len;
    pBuf = MapPtrToProcess((LPVOID)pSg->sb_buf, GetCallerProcess());

    EnterCriticalSection(&(pDisk->d_DiskCardCrit));

    if (pDisk->d_DiskCardState != STATE_OPENED) {
        DEBUGMSG(ZONE_IO,
          (TEXT("RAMDISK:DoDiskIO - Disk state != STATE_OPENED\r\n")));
        goto ddi_req_done;
    }

    //
    // Read or write sectors from/to disk.
    // NOTE: Multiple sectors may go in one scatter/gather buffer or one
    // sector may fit in multiple scatter/gather buffers.
    //
    DEBUGMSG(ZONE_IO, (TEXT("RAMDISK:DoDiskIO - Number of scatter/gather descriptors %d\r\n"), num_sg));
    while (num_sg) {
        DEBUGMSG(ZONE_IO, (TEXT("RAMDISK:DoDiskIO - Bytes left for this sg %d\r\n"), bytes_this_sg));
        pCard = pDisk->pbRAM + curr_byte;;
        if (Opcode == DISK_IOCTL_READ) {
            DEBUGMSG(ZONE_IO, (TEXT("RAMDISK:DoDiskIO - reading %d bytes at sector %d\r\n"),
                bytes_this_sg, (curr_byte - bytes_this_sg)/BYTES_PER_SECTOR));
            
            memcpy(pBuf, pCard, bytes_this_sg);
        } else {
            DEBUGMSG(ZONE_IO, (TEXT("RAMDISK:DoDiskIO - writing %d bytes at sector %d\r\n"),
                bytes_this_sg, (curr_byte - bytes_this_sg)/BYTES_PER_SECTOR));
            memcpy(pCard, pBuf, bytes_this_sg);
        }
        
        //
        // Use the next scatter/gather buffer
        //
        num_sg--;
        if (num_sg == 0) {
            break;
        }
        pSg++;
        pBuf = MapPtrToProcess((LPVOID)pSg->sb_buf, GetCallerProcess());
        bytes_this_sg = pSg->sb_len;
    }   // while sg

ddi_req_done:
    LeaveCriticalSection(&(pDisk->d_DiskCardCrit));

    if (pDisk->d_DiskCardState != STATE_OPENED) {
        //
        // Disk probably closed due to suspend/resume.
        //
        status = GetDiskStateError(pDisk->d_DiskCardState);
    }

ddi_exit:
    pSgr->sr_status = status;
    return status;
}   // DoDiskIO


//------------------------------------------------------------------------------
//
// GetDiskInfo - return disk info in response to DISK_IOCTL_GETINFO
//
//------------------------------------------------------------------------------
DWORD
GetDiskInfo(
    PDISK pDisk,
    PDISK_INFO pInfo
    )
{
    *pInfo = pDisk->d_DiskInfo;
    pInfo->di_flags |= DISK_INFO_FLAG_PAGEABLE;
    pInfo->di_flags &= ~DISK_INFO_FLAG_UNFORMATTED;
    return ERROR_SUCCESS;
}   // GetDiskInfo



//------------------------------------------------------------------------------
//
// SetDiskInfo - store disk info in response to DISK_IOCTL_SETINFO
//
//------------------------------------------------------------------------------
DWORD
SetDiskInfo(
    PDISK pDisk,
    PDISK_INFO pInfo
    )
{
    pDisk->d_DiskInfo = *pInfo;
    return ERROR_SUCCESS;
}   // SetDiskInfo



⌨️ 快捷键说明

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