View Full Version : How to address USB Flash Drive raw memory
roger
16th March 2009, 04:17 PM
I'm not at liberty to say why I need to do this. But this is the way it has to be done. So let's not quibble about how odd this seems.
I have a program that generates some binary data. I am required to write this to a USB flash drive in it's raw memory. The drive will be partially formatted in FAT32. I will write my data to the unformatted portion.
I am using Microsoft Visual Studio C++, and running Windows XP. Neither of those choices are negotiable.
I'm aware there are some commercial APIs out there, and we may very well go that way. But there are enough security and data safety issues that we may very well want/need to roll our own. Again, something I cannot go into.
If anyone can point me in the correct direction, that would be great. I'm guessing it's an hairy issue involving writing a driver, and really beyond what I reasonably want to do. Google has not been my friend in this matter, beyond finding commercial API's. Forgive me if I'm missing something obvious.
GreNME
16th March 2009, 04:44 PM
Um, that's going to depend. First off, can your program write to a raw, unformatted hard disk? If not, then you're probably outta luck without a hack to the controller chip on the USB drive, because I do believe that it interfaces with the memory on the stick like it would a disk drive.
Blue Mountain
16th March 2009, 05:24 PM
I can only give you pointers and not specifics, since I do not know the Windows APIs for this sort of thing.
The USB drive should present itself as a disc drive to the OS. As a disc, it should have tracks, heads, and cylinders, or Windows may abstract that away to a contiguous series of sectors. What you need to do is determine where the active partition ends and then use API calls to write to the sectors beyond that. Figuring out where the active partition ends may involve just some Windows API calls, or you may have to dig a little more deeply.
I'm not sure if you'll run into issues with security trying to do this. I know in Linux you usually need root authority to play around with raw discs as opposed to working with filesystems that reside in pre-allocated partitions.
You should be able to get some clues from open source projects that do low level stuff with disc drives under Windows (eg, partition programs and drivers for open-source filesystems such as ext2.)
Molinaro
16th March 2009, 06:41 PM
http://libusb-win32.sourceforge.net/
You could learn what you need by examining this open source package.
teddygrahams
16th March 2009, 06:47 PM
You can use \\physicalDriven with CreateFile to get access to the physical sectors (does not matter if formatted or not), but I think the physical memory can only accessed by the controller on the USB device.
jeremyp
16th March 2009, 07:22 PM
The USB drive should present itself as a disc drive to the OS. As a disc, it should have tracks, heads, and cylinders, or Windows may abstract that away to a contiguous series of sectors.
On the Macintosh, USB disks abstract as SCSI drives. This means it's just a sequence of blocks. It's probably the same on Windows, although I don't know what APIs are available on Windows to write to the raw disk. If it's anything like the Mac, you won't be able to, while the disk is mounted.
roger
16th March 2009, 09:50 PM
Um, that's going to depend. First off, can your program write to a raw, unformatted hard disk? If not, then you're probably outta luck without a hack to the controller chip on the USB drive, because I do believe that it interfaces with the memory on the stick like it would a disk drive.Well, I'm the programmer, so it can do whatever I'm able to program it to do.
roger
16th March 2009, 09:52 PM
The USB drive should present itself as a disc drive to the OS. As a disc, it should have tracks, heads, and cylinders, or Windows may abstract that away to a contiguous series of sectors. What you need to do is determine where the active partition ends and then use API calls to write to the sectors beyond that. Figuring out where the active partition ends may involve just some Windows API calls, or you may have to dig a little more deeply.Well, will it have sectors if it is unformatted in that range? It's basically going to be master record, blank (where I can write), and then formatted FAT32.
roger
16th March 2009, 09:55 PM
You can use \\physicalDriven with CreateFile to get access to the physical sectors (does not matter if formatted or not), but I think the physical memory can only accessed by the controller on the USB device.Okay, this sounds like what I'm looking for. The example in MSDN is a bit scant, but this sounds promising. Thanks!
BenBurch
16th March 2009, 11:04 PM
Well, I've done this; Written enough of a USB host stack to download data to a raw USB flash drive.
You basically address them as though they were a disk, a block at a time, using commands that are derived from the old SCSI commands.
BenBurch
16th March 2009, 11:06 PM
unsigned int SS_FATInit_Init(void)
{
switch(current_event.event_code)
{
case SE_Init:
{
return STATE SS_FATInit_Init;
}
case SE_INIT_FAT:
{
/* First task is to format and write the BPB (Boot Parameter Block)
* We only initialize the fields that MUST be there for the disk to be
* mounted. We do not include any boot code at all as this structure is
* never, ever intended to be booted!!!
*
* Here are the calculated parameters for this disk;
*
* Disk size: 15.9 MB 32640 physical sectors
* Bytes/Sector: 512
* Sectors/Cluster: 4
* Reserved Sectors: 1
* Root Directory Entries: 64
* FAT Copies: 2
* FAT Type: 16
* Sectors/FAT: 32
* Total Clusters: 8100
*
* Disk Map;
*
* 0 - BPD
* 1-32 - 1st FAT
* 33-64 - 2nd FAT
* 65-68 - Root Directory
* 69-32620 - Data Area
*
*/
EVENT e;
zeroBlock(buffer_out);
buffer_out[0] = 0xEB; /* BS_jumpboot - Does not point to any real code */
buffer_out[1] = 0x00;
buffer_out[2] = 0x90;
buffer_out[11] = DiskBlockSize % 256; /* BPB_BytsPerSec - DiskBlockSize */
buffer_out[12] = DiskBlockSize / 256;
buffer_out[13] = 4; /* BPB_SecPerClus */
buffer_out[14] = 1; /* BPB_RsvdSecCnt */
buffer_out[15] = 0;
buffer_out[16] = 2; /* BPB_NumFATs */
buffer_out[17] = 64 % 256; /* BPB_RootEntCnt */
buffer_out[18] = 64 / 256;
buffer_out[19] = 32640 % 256; /* BPB_TotSec16 - 16 MB volume size, fixed */
buffer_out[20] = 32640 / 256;
buffer_out[21] = 0xF0; /* BPB_Media - 0xF0 for removable media */
buffer_out[22] = 1 % 256; /* BPB_FATSz16 */
buffer_out[23] = 1 / 256;
buffer_out[38] = 0x29; /* BS_BootSig */
buffer_out[39] = testcount & 0xFF; /* BS_VolID */
buffer_out[40] = (testcount >> 8) & 0xFF;
buffer_out[41] = (testcount >> 16) & 0xFF;
buffer_out[42] = (testcount >> 24) & 0xFF;
buffer_out[43] = 'N'; /* BS_VolLab */
buffer_out[44] = 'O';
buffer_out[45] = ' ';
buffer_out[46] = 'N';
buffer_out[47] = 'A';
buffer_out[48] = 'M';
buffer_out[49] = 'E';
buffer_out[50] = ' ';
buffer_out[51] = ' ';
buffer_out[52] = ' ';
buffer_out[53] = ' ';
buffer_out[54] = 'F'; /* BS_FilSysType (Some non MS drivers look at this.) */
buffer_out[55] = 'A';
buffer_out[56] = 'T';
buffer_out[57] = '1';
buffer_out[58] = '6';
buffer_out[59] = ' ';
buffer_out[60] = ' ';
buffer_out[61] = ' ';
buffer_out[510] = 0x55; /* Required signature */
buffer_out[511] = 0xAA; /* Required signature */
e.state_machine_id = SM_USB_Reliable_Flash_Manager;
e.event_code = SE_Write_Flash_Block;
e.event_argument = (uint16) buffer_out;
e.event_argument2 = 0 ; /* BPB is block zero */
e.event_argument3 = current_event.state_machine_id;
enqevent(e);
return STATE SS_FATInit_BPB_Written;
}
}
return STATE SS_FATInit_Init; /* Just in case we head for the default exit, somehow. */
}
unsigned int SS_FATInit_BPB_Written(void)
{
switch(current_event.event_code)
{
case SE_Write_Flash_Block_Done:
{
/* Okay, the boot block is written. Now write the first FAT */
EVENT e;
int i;
zeroBlock(buffer_out);
buffer_out[0] = 0xF0; /* Removable */
buffer_out[1] = 0xFF;
buffer_out[2] = 0xFF;
buffer_out[3] = 0xFF;
currentSector = 1;
endSector = 32;
currentCluster = 3;
endCluster = 8100;
for(i = 4; i < DiskBlockSize; i += 2;)
{
if( currentCluster < endCluster )
{
buffer_out[i] = currentCluster % 256;
buffer_out[i+1] = currentCluster / 256;
currentCluster++;
}
else if ( currentCluster == endCluster )
{
buffer_out[i] = 0xFF;
buffer_out[1+1] = 0xFF;
currentCluster++;
}
else
{
buffer_out[i] = 0x00;
buffer_out[i+1] = 0x00;
currentCluster++;
}
}
e.state_machine_id = SM_USB_Reliable_Flash_Manager;
e.event_code = SE_Write_Flash_Block;
e.event_argument = (uint16) buffer_out;
e.event_argument2 = currentSector++;
e.event_argument3 = current_event.state_machine_id;
enqevent(e);
return STATE SS_FATInit_FAT1_Finish_Write;
}
}
return STATE SS_FATInit_BPB_Written; /* Just in case we head for the default exit, somehow. */
}
unsigned int SS_FATInit_FAT1_Finish_Write(void)
{
switch(current_event.event_code)
{
case SE_Write_Flash_Block_Done:
{
/* Write out each block of FAT with a single huge file allocated. */
EVENT e;
int i;
zeroBlock(buffer_out);
for(i = 0; i < DiskBlockSize; i += 2;)
{
if( currentCluster < endCluster )
{
buffer_out[i] = currentCluster % 256;
buffer_out[i+1] = currentCluster / 256;
currentCluster++;
}
else if ( currentCluster == endCluster )
{
buffer_out[i] = 0xFF;
buffer_out[1+1] = 0xFF;
currentCluster++;
}
else
{
buffer_out[i] = 0x00;
buffer_out[i+1] = 0x00;
currentCluster++;
}
}
e.state_machine_id = SM_USB_Reliable_Flash_Manager;
e.event_code = SE_Write_Flash_Block;
e.event_argument = (uint16) buffer_out;
e.event_argument2 = currentSector++;
e.event_argument3 = current_event.state_machine_id;
enqevent(e);
if( currentSector < endSector )
{
return STATE SS_FATInit_FAT1_Finish_Write;
}
else
{
return STATE SS_FATInit_FAT1_Done;
}
}
}
return STATE SS_FATInit_FAT1_Finish_Write; /* Just in case we head for the default exit, somehow. */
}
unsigned int SS_FATInit_FAT1_Done(void)
{
switch(current_event.event_code)
{
case SE_Write_Flash_Block_Done:
{
/* Okay, the first FAT is written. Now write the second FAT */
EVENT e;
int i;
zeroBlock(buffer_out);
buffer_out[0] = 0xF0; /* Removable */
buffer_out[1] = 0xFF;
buffer_out[2] = 0xFF;
buffer_out[3] = 0xFF;
currentSector = 33;
endSector = 64;
currentCluster = 3;
endCluster = 8100;
for(i = 4; i < DiskBlockSize; i += 2;)
{
if( currentCluster < endCluster )
{
buffer_out[i] = currentCluster % 256;
buffer_out[i+1] = currentCluster / 256;
currentCluster++;
}
else if ( currentCluster == endCluster )
{
buffer_out[i] = 0xFF;
buffer_out[1+1] = 0xFF;
currentCluster++;
}
else
{
buffer_out[i] = 0x00;
buffer_out[i+1] = 0x00;
currentCluster++;
}
}
e.state_machine_id = SM_USB_Reliable_Flash_Manager;
e.event_code = SE_Write_Flash_Block;
e.event_argument = (uint16) buffer_out;
e.event_argument2 = currentSector++;
e.event_argument3 = current_event.state_machine_id;
enqevent(e);
return STATE SS_FATInit_FAT2_Finish_Write;
}
}
return STATE SS_FATInit_FAT1_Done; /* Just in case we head for the default exit, somehow. */
}
unsigned int SS_FATInit_FAT2_Finish_Write(void)
{
switch(current_event.event_code)
{
case SE_Write_Flash_Block_Done:
{
/* Write out each block of FAT with a single huge file allocated. */
EVENT e;
int i;
zeroBlock(buffer_out);
for(i = 0; i < DiskBlockSize; i += 2;)
{
if( currentCluster < endCluster )
{
buffer_out[i] = currentCluster % 256;
buffer_out[i+1] = currentCluster / 256;
currentCluster++;
}
else if ( currentCluster == endCluster )
{
buffer_out[i] = 0xFF;
buffer_out[1+1] = 0xFF;
currentCluster++;
}
else
{
buffer_out[i] = 0x00;
buffer_out[i+1] = 0x00;
currentCluster++;
}
}
e.state_machine_id = SM_USB_Reliable_Flash_Manager;
e.event_code = SE_Write_Flash_Block;
e.event_argument = (uint16) buffer_out;
e.event_argument2 = currentSector++;
e.event_argument3 = current_event.state_machine_id;
enqevent(e);
if( currentSector < endSector )
{
return STATE SS_FATInit_FAT2_Finish_Write;
}
else
{
return STATE SS_FATInit_FAT2_Done;
}
}
}
return STATE SS_FATInit_FAT2_Finish_Write; /* Just in case we head for the default exit, somehow. */
}
unsigned int SS_FATInit_FAT2_Done(void)
{
switch(current_event.event_code)
{
case SE_Write_Flash_Block_Done:
{
/* Okay, the second FAT is written. Now write the directory entry */
EVENT e;
int i;
uint32 totalsize;
zeroBlock(buffer_out);
buffer_out[0] = 'R'; /* DIR_Name */
buffer_out[1] = 'E';
buffer_out[2] = 'A';
buffer_out[3] = 'D';
buffer_out[4] = 'I';
buffer_out[5] = 'N';
buffer_out[6] = 'G';
buffer_out[7] = 'S';
buffer_out[8] = 'D';
buffer_out[9] = 'A';
buffer_out[10] = 'T';
buffer_out[11] = 0x01; /* DIR_Attr 0x01 = Read-Only */
/* We allow time and date to be zero, since we have no clock */
buffer_out[26] = 2 % 256; /* DIR_FstClusLO = Low word of first cluster number */
buffer_out[27] = 2 / 256;
totalsize = 8100 * 4 * 512 ; /* total size of the huge file */
buffer_out[28] = totalsize & 0xFF; /* DIR_FileSize */
buffer_out[29] = (totalsize >> 8) & 0xFF;
buffer_out[30] = (totalsize >> 16) & 0xFF;
buffer_out[31] = (totalsize >> 24) & 0xFF;
/* That's it. The rest of the root directory gets filled with zeroes */
endSector = 68;
e.state_machine_id = SM_USB_Reliable_Flash_Manager;
e.event_code = SE_Write_Flash_Block;
e.event_argument = (uint16) buffer_out;
e.event_argument2 = currentSector++;
e.event_argument3 = current_event.state_machine_id;
enqevent(e);
return STATE SS_FATInit_RootDir_Finish_Write;
}
}
return STATE SS_FATInit_FAT2_Done; /* Just in case we head for the default exit, somehow. */
}
unsigned int SS_FATInit_RootDir_Finish_Write(void)
{
switch(current_event.event_code)
{
case SE_Write_Flash_Block_Done:
{
EVENT e;
int i;
uint32 totalsize;
zeroBlock(buffer_out);
e.state_machine_id = SM_USB_Reliable_Flash_Manager;
e.event_code = SE_Write_Flash_Block;
e.event_argument = (uint16) buffer_out;
e.event_argument2 = currentSector++;
e.event_argument3 = current_event.state_machine_id;
enqevent(e);
if( currentSector < endSector )
{
return STATE SS_FATInit_RootDir_Finish_Write;
}
else
{
return STATE SS_FAT_INIT_DONE;
}
}
}
return STATE SS_FATInit_RootDir_Finish_Write; /* Just in case we head for the default exit, somehow. */
}
unsigned int SS_FAT_INIT_DONE(void)
{
switch(current_event.event_code)
{
case SE_Write_Flash_Block_Done:
{
EVENT e;
e.state_machine_id = SM_USB_Flash_Manager;
e.event_code = SE_FAT_INIT_DONE;
enqevent(e);
return STATE SS_FAT_INIT_DONE; /* We stall in this state after emitting status */
}
}
return STATE SS_FAT_INIT_DONE; /* Just in case we head for the default exit, somehow. */
}
/*
Now, the FAT structure is initialized and we can just write out our data
starting at block 69.
*/
Blue Mountain
17th March 2009, 07:42 AM
Well, will it have sectors if it is unformatted in that range? It's basically going to be master record, blank (where I can write), and then formatted FAT32.
Yes. A disc has sectors on it in the same way a book has pages of paper in it. A filesystem (FAT, FAT-32, NTFS, ext2 are all filesystems) is a bit like an index page at the start of the book that indicates which pages contain useful information and which ones don't. Just because there isn't an index page in the book doesn't mean you can't open the book to a random page and scribble something on it.
Suppose you have a book with 500 pages in it. What you're trying to do is set up an index page that says "this book has only 100 pages in it, and here are the contents." The other 400 pages are sort of "hidden"; there's no index for them. But the pages still exist, and you can still write stuff on them and read them.
roger
18th March 2009, 08:30 AM
Blue - okay, that makes sense. I guess my waffling on that issue is that I know the 'disk' is not a disk, it's flash memory. But of course that is a pointless distinction - the issue is how the controller on the device presents the memory to the OS. You could use a real disk drive as memory, if the controller was set up that way. I was just wrongly thinking unformatted = no blocks.
Ben - that's awesome! Very helpful, indeed. Thanks!
roger
18th March 2009, 09:27 AM
So, to summarize, for WinXP, I should (in pseudocode, no effort made to get parameters right)
handle = CreateFile (physicaldrive);
SetFilePointer (handle, address_of_sector_to_write_to);
WriteFile (handle, buffer);
jsiv
18th March 2009, 10:25 AM
That should work fine provided the user has the appropriate access rights and there's no sharing violation. Obtaining the name of the physical drive can be a bit more work though, especially if it has no mounted volumes (and you have to start enumerating the physical drives, maybe with SetupAPI). If it does though, DeviceIoControl (http://msdn.microsoft.com/en-us/library/aa363216%28VS.85%29.aspx) can be used to get the physical drive from a volume, and in turn also details about the disk and partitions (look under Disk Management Control Codes (http://msdn.microsoft.com/en-us/library/aa363979%28VS.85%29.aspx)) which you'll probably need to avoid corrupting the disk.
This does seem like a bit of a strange thing to do though.
roger
18th March 2009, 12:53 PM
Okay, I coded up a test, it appears to work. Thanks for the help, everyone. I'm sure I was using the wrong terms, but google was getting me nowhere, probably because of my bad assumption that I had to address it like memory, not a drive.
I agree, it is not only strange, it is dumb. But I don't get to decide this.
Blue Mountain
18th March 2009, 03:07 PM
Okay, I coded up a test, it appears to work. Thanks for the help, everyone. I'm sure I was using the wrong terms, but google was getting me nowhere, probably because of my bad assumption that I had to address it like memory, not a drive.
I agree, it is not only strange, it is dumb.
I don't see it as dumb. The USB device declares itself to be a Mass Storage device (class 08h). The USB standard specifies the types of calls that can be made on the USB bus to interact with such a device.
To make life easier for the programmers, the OS can abstract all that simply by working with the USB device as if it was a disc. The fact it uses Flash memory to store the data and not spinning discs under moving read/write heads is a detail.
Actually, I've described how Linux deals with USB flash drives: it can abstract them as SCSI discs. From the code that BenBurch posted, it appears Windows bypasses the disc abstraction and works with physical and/or logical volumes. It's more direct, but also less useful from a user's point of view. Under Linux, for example, I can use 'fdisk' to write a DOS disk label on a USB flash drive and partition into two partitions, then format the first one as FAT and the other as ext2. Windows doesn't give you that versatility.
GreNME
18th March 2009, 03:21 PM
Okay, I coded up a test, it appears to work. Thanks for the help, everyone. I'm sure I was using the wrong terms, but google was getting me nowhere, probably because of my bad assumption that I had to address it like memory, not a drive.
I agree, it is not only strange, it is dumb. But I don't get to decide this.
As Blue Mountain said, I don't think it was a bad assumption on your part. The abstraction treats it like a disk drive, which considering the actual hardware you're dealing with seems counterintuitive. But it works from the OS level, which means the configuration of the hardware was confusing the direction you were facing. That's where the usefulness of the net comes in, to give you other ideas you hadn't gotten around to considering yet.
Cool that it works. Is it something you can't get into details over for work reasons? I'm actually interested in what you're doing with it.
jsiv
18th March 2009, 04:27 PM
What I meant was strange (or rather, unusual) was to have a memory stick with both a file system and a section that is written directly to by some software, not how the drives work. But if that's what they want, then that's what they want.
Actually, I've described how Linux deals with USB flash drives: it can abstract them as SCSI discs. From the code that BenBurch posted, it appears Windows bypasses the disc abstraction and works with physical and/or logical volumes. It's more direct, but also less useful from a user's point of view. Under Linux, for example, I can use 'fdisk' to write a DOS disk label on a USB flash drive and partition into two partitions, then format the first one as FAT and the other as ext2. Windows doesn't give you that versatility.
BenBurch's code is platform-neutral, there's nothing Windows-related in it. Windows abstracts the disk the same way as on Linux. You can access the Mass Storage Device directly (which you never would, really), the physical disk exposed by the driver (what you fdisk to on Linux), or any volumes on it. The lower down the chain you go, the more complex it obviously gets. There's nothing special about memory sticks, they follow the same scheme as any other disk.
roger
18th March 2009, 04:32 PM
I don't see it as dumb..No, I meant this requirement to have a flash drive used partially as flash, and then write other data to it not using the file system. The application requirements.
roger
18th March 2009, 04:38 PM
For the curious, the chain of commands is (leaving out a bunch of parameter)
// open the drive
CreateFile (TEXT("\\\\.\\K:"), ...);
// get the sector size
DeviceIoControl(h, IOCTL_DISK_GET_DRIVE_GEOMETRY,...);
// lock it so we have exclusive access
DeviceIoControl(h, FSCTL_LOCK_VOLUME, ...);
// unmount so we can read/write
DeviceIoControl(h, FSCTL_DISMOUNT_VOLUME,...);
// go to beginning of where we want to write
SetFilePointer (h, start,...);
// write a buffer to the drive
WriteFile (h, buffer,...);
// unlock the mother
DeviceIoControl(h, FSCTL_UNLOCK_VOLUME,...)
// and goodbye
CloseHandle(h);
I don't assert this is perfect, but it let me write data, then read it back (by changing WriteFile to ReadFile). I also read suggestions that none of this would work in Vista due to security restrictions.
roger
18th March 2009, 04:41 PM
Is it something you can't get into details over for work reasons? Yes. Sorry.
jsiv
18th March 2009, 04:56 PM
It's still possible in Vista, but you need an exclusive lock to touch critical areas of the disk, ie the MBR or any mounted file system (which is what you appear to be doing in your example. Is that what you really want?)
Windows doesn't care about the integrity of anything else.
roger
18th March 2009, 05:31 PM
It's still possible in Vista, but you need an exclusive lock to touch critical areas of the disk, ie the MBR or any mounted file system (which is what you appear to be doing in your example. Is that what you really want?)Hmm, looking back at the code, the lock and unmount don't appear to be necessary. I was having trouble making the code work, but I was calling CreateFile with some wrong parameters, and the lock and unmount found their way into the code while trying to figure out my problem. I just commented them out and the read/write still works.
jsiv
18th March 2009, 05:45 PM
Right, but when you call CreateFile on K:\ you aren't opening the physical drive, you're only opening the file system mounted on K:. When you then lock and write to it, you are actually overwriting part of that file system.
It sounds like you really want to open the physical drive, then seek to a part of it not occupied by the file system and then read/write to it.
To get the name of the physical drive from a mounted file system you could do something like this:
#define _WIN32_WINNT 0x0501 // XP
#define WIN32_LEAN_AND_MEAN
#define STRICT
#include <stdio.h>
#include <windows.h>
#include <winioctl.h>
BOOL GetPhysicalFromVolume(__in const WCHAR *volume, __out WCHAR *physicaldrive)
{
HANDLE vol = CreateFile(volume, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(vol == INVALID_HANDLE_VALUE)
return FALSE;
DWORD bytesret;
VOLUME_DISK_EXTENTS de;
BOOL ret = DeviceIoControl(vol, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0,
&de, sizeof(VOLUME_DISK_EXTENTS), &bytesret, NULL);
if(!ret)
{
CloseHandle(vol);
return FALSE;
}
wsprintf(physicaldrive, L"\\\\.\\PhysicalDrive%d", de.Extents->DiskNumber);
CloseHandle(vol);
return TRUE;
}
int wmain(int argc, WCHAR *argv[])
{
WCHAR diskname[512];
GetPhysicalFromVolume(L"\\\\.\\K:", diskname);
wprintf(L"Volume is on %s\n", diskname);
HANDLE disk = CreateFile(diskname, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(disk == INVALID_HANDLE_VALUE)
wprintf(L"failed to open %s: %d\n", diskname, GetLastError());
else
CloseHandle(disk);
return 0;
}
roger
18th March 2009, 05:52 PM
Oh, okay, thanks. In post 14 I was using physical drive, but along the way I wrote some code to get the physical drive from the K:\, and somehow the K:\ stayed in the code when I was slimming it down. Fortunately this is just some test code I'm playing with while my main computer is being repaired. Good catch!
jsiv
18th March 2009, 05:58 PM
Hehe, well there you go. There should be no need to lock or unmount anything then.
There's a list of the conditions here: http://msdn.microsoft.com/en-us/library/cc835968.aspx
BenBurch
19th March 2009, 11:27 AM
If you should ever want to do this from a device rather than Windows, Cypress Semiconductor makes a good USB host device micro-controller.
© 2001-2009, James Randi Educational Foundation. All Rights Reserved.
vBulletin® v3.7.7, Copyright ©2000-2012, Jelsoft Enterprises Ltd.