'소스코드'에 해당되는 글 2건

  1. 2007.10.18 Window I/O 관련 윈도우에서 Physical Drive 직접 읽고 쓰기
  2. 2007.08.29 Virtual-Key Codes 4
개발이야기2007. 10. 18. 19:26

원본:요기 

윈도우에서 Physical Drive 직접 읽고 쓰기

  • 드라이브 열기
  1. HANDLE OpenDrive( int iPhysicalDriveNumber )
    {
        HANDLE hDevice;
        char vcDriveName[ 30 ];
  2.     // HDD를 실수로 지우는걸 방지하기 위함

        if( iPhysicalDriveNumber == 0 )
        {
            return INVALID_HANDLE_VALUE;
        }

  3.     // Physical Drive를 연다.
        sprintf( vcDriveName, "\\\\.\\PhysicalDrive%d", iPhysicalDriveNumber );
        hDevice = CreateFile( vcDriveName, GENERIC_READ | GENERIC_WRITE,
            FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
        return hDevice;
    }

  • 드라이브 읽기
  1. BOOL ReadSector( HANDLE hDevice, DWORD dwSectorOffset, BYTE* pbBuffer,
                     int iSectorCount )
    {
        DWORD dwLow;
        DWORD dwHigh;
        DWORD dwRet;
        DWORD dwRead;
        DWORD dwErrorCode;
  2.     // 움직일 위치는 byte 단위로 되어야 한다.
        // 결국 dwSectorOffset에 512를 곱해줘야 한다.
        dwLow = ( dwSectorOffset << 9 );
        dwHigh = ( dwSectorOffset >> 23 );
  3.     // File Pointer를 이동한다.
        dwRet = SetFilePointer( hDevice, dwLow, &dwHigh, FILE_BEGIN );
        if( dwRet == INVALID_SET_FILE_POINTER )
        {
            return FALSE;
        }
  4.     // Sector를 읽는다.
        if( ReadFile( hDevice, pbBuffer, iSectorCount * SECTORSIZE, &dwRead,
            NULL ) == FALSE )
        {
            dwErrorCode = GetLastError();
            return FALSE;
        }
  5.     return TRUE;
    }
  • 드라이브 쓰기
  1. BOOL WriteSector( HANDLE hDevice, DWORD dwSectorOffset, BYTE* pbBuffer,
                     int iSectorCount )
    {
        DWORD dwLow;
        DWORD dwHigh;
        DWORD dwRet;
        DWORD dwWrite;
        DWORD dwErrorCode;
  2.     // 움직일 위치는 byte 단위로 되어야 한다.
        // 결국 dwSectorOffset에 512를 곱해줘야 한다.
        dwLow = ( dwSectorOffset << 9 );
        dwHigh = ( dwSectorOffset >> 23 );
  3.     // File Pointer를 이동한다.
        dwRet = SetFilePointer( hDevice, dwLow, &dwHigh, FILE_BEGIN );
        if( dwRet == INVALID_SET_FILE_POINTER )
        {
            return FALSE;
        }
  4.     // Sector를 쓴다.
        if( WriteFile( hDevice, pbBuffer, iSectorCount * SECTORSIZE, &dwWrite,
            NULL ) == FALSE )
        {
            dwErrorCode = GetLastError();
            return FALSE;
        }
  5.     gs_dwTotalWriteSectorCount += iSectorCount;
        return TRUE;
    }
  • 드라이브 닫기
  1. void CloseDrive( HANDLE hDevice )
    {
        CloseHandle( hDevice );
    }

Drive의 Geometry 읽기

Geometry정보에는 CHS 값이 들어있기 때문에 유용하게 쓸 수 있다.

  1. BOOL GetDriveGeometry( int iPhysicalDriveNumber, GEOMETRY* pstGeometry )
    {
        HANDLE hDevice;
        BOOL bRet;
        DWORD dwOutBytes;
        char vcDriveName[ 30 ];
        DISK_GEOMETRY stWindowGeometry;
  2.     // Physical Drive Number를 저장한다.
        sprintf( vcDriveName, "\\\\.\\PhysicalDrive%d", iPhysicalDriveNumber );
  3.     hDevice = CreateFile( vcDriveName, 0, FILE_SHARE_READ |
            FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
  4.     if( hDevice == INVALID_HANDLE_VALUE )
        {
            return FALSE;
        }
  5.     bRet = DeviceIoControl( hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY,
            NULL, 0, &stWindowGeometry, sizeof( DISK_GEOMETRY ), &dwOutBytes,
            NULL );
  6.     CloseHandle( hDevice );
  7.     // 지금은 윈도우 Geometry와 같은 Geometry를 사용한다.
        memcpy( pstGeometry, &stWindowGeometry, sizeof( DISK_GEOMETRY ) );
  8.     return bRet;
    }

Drive Descriptor 얻기

Descriptor에 보면 해당 드라이브의 제품명과 리비전 번호 같은 걸 알 수 있다.

  1. BOOL GetDeviceDescriptor( char* pcDevice, PSTORAGE_DEVICE_DESCRIPTOR pstDesc )
    {
        HANDLE hDevice;
        STORAGE_PROPERTY_QUERY  stQuery;
        DWORD dwOut;
        BOOL bRet;
  2.     memset( pstDesc, 0, sizeof(STORAGE_DEVICE_DESCRIPTOR) );
  3.     // Device를 Open한다.
        hDevice = CreateFile( pcDevice, GENERIC_READ, FILE_SHARE_READ |
            FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
        if( hDevice == INVALID_HANDLE_VALUE )
        {
            return FALSE;
        }
  4.     pstDesc->Size = sizeof( STORAGE_DEVICE_DESCRIPTOR );
  5.     // Device Io Control을 호출한다.
        stQuery.PropertyId = StorageDeviceProperty;
        stQuery.QueryType = PropertyStandardQuery;
  6.     bRet = DeviceIoControl( hDevice, IOCTL_STORAGE_QUERY_PROPERTY,
                &stQuery, sizeof( STORAGE_PROPERTY_QUERY ),
                pstDesc, pstDesc->Size, &dwOut, NULL);                
        if( bRet == FALSE )
        {
            return FALSE;
        }
  7.     CloseHandle( hDevice );
        return TRUE;
    }

Drive 문자로 Physical Index 얻기

드라이브 문자로 Physical Index를 얻는 방법은 VOLUME 정보를 이용하면 된다.

  1. int GetPhysicalDriveNumber( char cDriveName )
    {
        HANDLE hDevice;
        DWORD dwOut;
        BOOL bRet;
        char vcDriveName[ 40 ];
        VOLUME_DISK_EXTENTS* pstVolumeData;
        int iDiskNumber;
  2.     // 메모리를 할당한다.
        pstVolumeData = ( VOLUME_DISK_EXTENTS* ) malloc( VOLUMEDISKSIZE );
        if( pstVolumeData == NULL )
        {
            return -1;
        }
  3.     // 해당 Drive의 정보를 얻는다.
        sprintf( vcDriveName, "\\\\?\\%c:", cDriveName );
        // Device를 Open한다.
        hDevice = CreateFile( vcDriveName, GENERIC_READ, FILE_SHARE_READ |
            FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
        if( hDevice == INVALID_HANDLE_VALUE )
        {
            return -1;
        }
  4.     // Device Io Control을 호출한다.
        bRet = DeviceIoControl( hDevice, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
                NULL, 0, pstVolumeData, VOLUMEDISKSIZE, &dwOut, NULL );
        if( bRet == FALSE )
        {
            free( pstVolumeData );
            return -1;
        }
        CloseHandle( hDevice );
  5.     // Disk 정보가 1보다 작으면 실패
        if( pstVolumeData->NumberOfDiskExtents < 1 )
        {
            free( pstVolumeData );
            return -1;
        }
  6.     iDiskNumber = pstVolumeData->Extents[ 0 ].DiskNumber;
        free( pstVolumeData );
  7.     return iDiskNumber;
    }


Logical Drive와 Physical Drive 간의 매치방법

1. 일단 Logical Drive를 검색한다.
-> GetDriveType() 함수를 이용
2. 해당 Drvie를 열어서 Volume 정보를 얻음
-> "\\?\c" 와 같은 형태로 CreateFile() 호출
-> IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS를 날려서 Physical Drive 정보를 얻음
-> 리더기에 데이터가 연결되어있지 않으면 DeviceIoControl에서 문제 발생

00 Window I/O 관련

Posted by krsuncom
개발이야기2007. 8. 29. 13:45

 

Virtual-Key Codes

Send Feedback

The following table shows the symbolic constant names, hexadecimal values, and keyboard equivalents for the virtual-key codes used by the Microsoft Windows CE operating system. The codes are listed in numeric order. You can combine any of the codes with a modifier key to create a hot key.

Virtual key codes

Symbolic constant
Hexadecimal value
Mouse or keyboard equivalent

VK_LBUTTON
01
Left mouse button

VK_RBUTTON
02
Right mouse button

VK_CANCEL
03
Control-break processing

VK_MBUTTON
04
Middle mouse button on a three-button mouse

0507
Undefined

VK_BACK
08
BACKSPACE key

VK_TAB
09
TAB key

0A0B
Undefined

VK_CLEAR
0C
CLEAR key

VK_RETURN
0D
ENTER key

0E0F
Undefined

VK_SHIFT
10
SHIFT key

VK_CONTROL
11
CTRL key

VK_MENU
12
ALT key

VK_PAUSE
13
PAUSE key

VK_CAPITAL
14
CAPS LOCK key

1519
Reserved for Kanji systems

1A
Undefined

VK_ESCAPE
1B
ESC key

1C1F
Reserved for Kanji systems

VK_SPACE
20
SPACEBAR

VK_PRIOR
21
PAGE UP key

VK_NEXT
22
PAGE DOWN key

VK_END
23
END key

VK_HOME
24
HOME key

VK_LEFT
25
LEFT ARROW key

VK_UP
26
UP ARROW key

VK_RIGHT
27
RIGHT ARROW key

VK_DOWN
28
DOWN ARROW key

VK_SELECT
29
SELECT key

2A
Specific to original equipment manufacturer

VK_EXECUTE
2B
EXECUTE key

VK_SNAPSHOT
2C
PRINT SCREEN key

VK_INSERT
2D
INS key

VK_DELETE
2E
DEL key

VK_HELP
2F
HELP key

3A40
Undefined

VK_LWIN
5B
Left Windows key on a Microsoft Natural Keyboard

VK_RWIN
5C
Right Windows key on a Microsoft Natural Keyboard

VK_APPS
5D
Applications key on a Microsoft Natural Keyboard

5E5F
Undefined

VK_NUMPAD0
60
Numeric keypad 0 key

VK_NUMPAD1
61
Numeric keypad 1 key

VK_NUMPAD2
62
Numeric keypad 2 key

VK_NUMPAD3
63
Numeric keypad 3 key

VK_NUMPAD4
64
Numeric keypad 4 key

VK_NUMPAD5
65
Numeric keypad 5 key

VK_NUMPAD6
66
Numeric keypad 6 key

VK_NUMPAD7
67
Numeric keypad 7 key

VK_NUMPAD8
68
Numeric keypad 8 key

VK_NUMPAD9
69
Numeric keypad 9 key

VK_MULTIPLY
6A
Multiply key

VK_ADD
6B
Add key

VK_SEPARATOR
6C
Separator key

VK_SUBTRACT
6D
Subtract key

VK_DECIMAL
6E
Decimal key

VK_DIVIDE
6F
Divide key

VK_F1
70
F1 key

VK_F2
71
F2 key

VK_F3
72
F3 key

VK_F4
73
F4 key

VK_F5
74
F5 key

VK_F6
75
F6 key

VK_F7
76
F7 key

VK_F8
77
F8 key

VK_F9
78
F9 key

VK_F10
79
F10 key

VK_F11
7A
F11 key

VK_F12
7B
F12 key

VK_F13
7C
F13 key

VK_F14
7D
F14 key

VK_F15
7E
F15 key

VK_F16
7F
F16 key

VK_F17
80H
F17 key

VK_F18
81H
F18 key

VK_F19
82H
F19 key

VK_F20
83H
F20 key

VK_F21
84H
F21 key

VK_F22
85H
F22 key

(PPC only) Key used to lock device.

VK_F23
86H
F23 key

VK_F24
87H
F24 key

888F
Unassigned

VK_NUMLOCK
90
NUM LOCK key

VK_SCROLL
91
SCROLL LOCK key

VK_LSHIFT
0xA0
Left SHIFT

VK_RSHIFT
0xA1
Right SHIFT

VK_LCONTROL
0xA2
Left CTRL

VK_RCONTROL
0xA3
Right CTRL

VK_LMENU
0xA4
Left ALT

VK_RMENU
0xA5
Right ALT

BA-C0
Specific to original equipment manufacturer; reserved. See following tables.

C1-DA
Unassigned

DB-E2
Specific to original equipment manufacturer; reserved. See following tables.

E3 – E4
Specific to original equipment manufacturer

E5
Unassigned

E6
Specific to original equipment manufacturer

VK_PACKET
E7
Used to pass Unicode characters as if they were keystrokes. If VK_PACKET is used with SendInput, then the Unicode character to be delivered should be placed into the lower 16 bits of the scan code. If a keyboard message is removed from the message queue and the virtual key is VK_PACKET, then the Unicode character will be the upper 16 bits of the lparam.

E8
Unassigned

E9-F5
Specific to original equipment manufacturer

VK_ATTN
F6
ATTN key

VK_CRSEL
F7
CRSEL key

VK_EXSEL
F8
EXSEL key

VK_EREOF
F9
Erase EOF key

VK_PLAY
FA
PLAY key

VK_ZOOM
FB
ZOOM key

VK_NONAME
FC
Reserved for future use

VK_PA1
FD
PA1 key

VK_OEM_CLEAR
FE
CLEAR key

VK_KEYLOCK
F22
Key used to lock device

Original equipment manufacturers should make special note of the VK key ranges reserved for specific original equipment manufacturer use: 2A, DBE4, E6, and E9F5.

In addition to the VK key assignments in the previous table, Microsoft has assigned the following specific original equipment manufacturer VK keys.

Symbolic constant
Hexadecimal value
Mouse or keyboard equivalent

VK_OEM_SCROLL
0x91
None

VK_OEM_1
0xBA
";:" for US

VK_OEM_PLUS
0xBB
"+" any country/region

VK_OEM_COMMA
0xBC
"," any country/region

VK_OEM_MINUS
0xBD
"-" any country/region

VK_OEM_PERIOD
0xBE
"." any country/region

VK_OEM_2
0xBF
"/?" for US

VK_OEM_3
0xC0
"`~" for US

VK_OEM_4
0xDB
"[{" for US

VK_OEM_5
0xDC
"\|" for US

VK_OEM_6
0xDD
"]}" for US

VK_OEM_7
0xDE
"'"" for US

VK_OEM_8
0xDF
None

VK_OEM_AX
0xE1
AX key on Japanese AX keyboard

VK_OEM_102
0xE2
"<>" or "\|" on RT 102-key keyboard

For East Asian Input Method Editors (IMEs) the following additional virtual keyboard definitions must be observed.

Symbolic constant
Hexadecimal value
Description

VK_DBE_ALPHANUMERIC
0x0f0
Changes the mode to alphanumeric.

VK_DBE_KATAKANA
0x0f1
Changes the mode to Katakana.

VK_DBE_HIRAGANA
0x0f2
Changes the mode to Hiragana.

VK_DBE_SBCSCHAR
0x0f3
Changes the mode to single-byte characters.

VK_DBE_DBCSCHAR
0x0f4
Changes the mode to double-byte characters.

VK_DBE_ROMAN
0x0f5
Changes the mode to Roman characters.

VK_DBE_NOROMAN
0x0f6
Changes the mode to non-Roman characters.

VK_DBE_ENTERWORDREGISTERMODE
0x0f7
Activates the word registration dialog box.

VK_DBE_ENTERIMECONFIGMODE
0x0f8
Activates a dialog box for setting up an IME environment.

VK_DBE_FLUSHSTRING
0x0f9
Deletes the undetermined string without determining it.

VK_DBE_CODEINPUT
0x0fa
Changes the mode to code input.

VK_DBE_NOCODEINPUT
0x0fb
Changes the mode to no-code input.

Original equipment manufacturers should not use the unassigned portions of the VK mapping tables. Microsoft will assign these values in the future. If manufacturers require additional VK mappings, they should reuse some of the current manufacturer-specific and vendor-specific assignments.

See Also

Using Virtual-Key Codes | Manufacturer-specific Virtual-Key Codes

Virtual-Key Codes

Posted by krsuncom