📄 diskio.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 + -