| /* |
| * Win32 device functions |
| * |
| * Copyright 1998 Marcus Meissner |
| */ |
| |
| #include <errno.h> |
| #include <assert.h> |
| #include <stdlib.h> |
| #include <unistd.h> |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include <sys/mman.h> |
| #include <fcntl.h> |
| #include <string.h> |
| #include <time.h> |
| #include "windows.h" |
| #include "winbase.h" |
| #include "winerror.h" |
| #include "file.h" |
| #include "process.h" |
| #include "mmsystem.h" |
| #include "heap.h" |
| #include "debug.h" |
| #include "winioctl.h" |
| |
| void DEVICE_Destroy(K32OBJ *dev); |
| const K32OBJ_OPS DEVICE_Ops = |
| { |
| NULL, /* signaled */ |
| NULL, /* satisfied */ |
| NULL, /* add_wait */ |
| NULL, /* remove_wait */ |
| NULL, /* read */ |
| NULL, /* write */ |
| DEVICE_Destroy /* destroy */ |
| }; |
| |
| /* The device object */ |
| typedef struct |
| { |
| K32OBJ header; |
| int mode; |
| char *devname; |
| } DEVICE_OBJECT; |
| |
| HANDLE32 |
| DEVICE_Open(LPCSTR filename, DWORD access) { |
| DEVICE_OBJECT *dev; |
| HANDLE32 handle; |
| |
| dev = HeapAlloc( SystemHeap, 0, sizeof(FILE_OBJECT) ); |
| if (!dev) |
| return INVALID_HANDLE_VALUE32; |
| dev->header.type = K32OBJ_DEVICE_IOCTL; |
| dev->header.refcount = 0; |
| dev->mode = access; |
| dev->devname = HEAP_strdupA(SystemHeap,0,filename); |
| |
| handle = HANDLE_Alloc( PROCESS_Current(), &(dev->header), |
| FILE_ALL_ACCESS | GENERIC_READ | |
| GENERIC_WRITE | GENERIC_EXECUTE /*FIXME*/, TRUE ); |
| /* If the allocation failed, the object is already destroyed */ |
| if (handle == INVALID_HANDLE_VALUE32) dev = NULL; |
| return handle; |
| } |
| |
| void |
| DEVICE_Destroy(K32OBJ *dev) { |
| assert(dev->type == K32OBJ_DEVICE_IOCTL); |
| } |
| |
| /**************************************************************************** |
| * DeviceIoControl (KERNEL32.188) |
| * This is one of those big ugly nasty procedure which can do |
| * a million and one things when it comes to devices. It can also be |
| * used for VxD communication. |
| * |
| * A return value of FALSE indicates that something has gone wrong which |
| * GetLastError can decypher. |
| */ |
| BOOL32 WINAPI DeviceIoControl(HANDLE32 hDevice, DWORD dwIoControlCode, |
| LPVOID lpvlnBuffer, DWORD cblnBuffer, |
| LPVOID lpvOutBuffer, DWORD cbOutBuffer, |
| LPDWORD lpcbBytesReturned, |
| LPOVERLAPPED lpOverlapped) |
| { |
| DEVICE_OBJECT *dev = (DEVICE_OBJECT *)HANDLE_GetObjPtr( |
| PROCESS_Current(), hDevice, K32OBJ_DEVICE_IOCTL, 0 /*FIXME*/ ); |
| |
| FIXME(win32, "(%ld,%ld,%p,%ld,%p,%ld,%p,%p), stub\n", |
| hDevice,dwIoControlCode,lpvlnBuffer,cblnBuffer, |
| lpvOutBuffer,cbOutBuffer,lpcbBytesReturned,lpOverlapped |
| ); |
| |
| if (!dev) |
| { |
| SetLastError( ERROR_INVALID_PARAMETER ); |
| return FALSE; |
| } |
| |
| /* Check if this is a user defined control code for a VxD */ |
| if( HIWORD( dwIoControlCode ) == 0 ) |
| { |
| /* FIXME: Set appropriate error */ |
| FIXME(win32," VxD device %s msg\n",dev->devname); |
| |
| if (!strcmp(dev->devname,"VTDAPI")) |
| { |
| switch (dwIoControlCode) |
| { |
| case 5: if (lpvOutBuffer && (cbOutBuffer>=4)) |
| *(DWORD*)lpvOutBuffer = timeGetTime(); |
| if (lpcbBytesReturned) |
| *lpcbBytesReturned = 4; |
| return TRUE; |
| default: |
| break; |
| } |
| |
| } |
| } |
| else |
| { |
| switch( dwIoControlCode ) |
| { |
| case FSCTL_DELETE_REPARSE_POINT: |
| case FSCTL_DISMOUNT_VOLUME: |
| case FSCTL_GET_COMPRESSION: |
| case FSCTL_GET_REPARSE_POINT: |
| case FSCTL_LOCK_VOLUME: |
| case FSCTL_QUERY_ALLOCATED_RANGES: |
| case FSCTL_SET_COMPRESSION: |
| case FSCTL_SET_REPARSE_POINT: |
| case FSCTL_SET_SPARSE: |
| case FSCTL_SET_ZERO_DATA: |
| case FSCTL_UNLOCK_VOLUME: |
| case IOCTL_DISK_CHECK_VERIFY: |
| case IOCTL_DISK_EJECT_MEDIA: |
| case IOCTL_DISK_FORMAT_TRACKS: |
| case IOCTL_DISK_GET_DRIVE_GEOMETRY: |
| case IOCTL_DISK_GET_DRIVE_LAYOUT: |
| case IOCTL_DISK_GET_MEDIA_TYPES: |
| case IOCTL_DISK_GET_PARTITION_INFO: |
| case IOCTL_DISK_LOAD_MEDIA: |
| case IOCTL_DISK_MEDIA_REMOVAL: |
| case IOCTL_DISK_PERFORMANCE: |
| case IOCTL_DISK_REASSIGN_BLOCKS: |
| case IOCTL_DISK_SET_DRIVE_LAYOUT: |
| case IOCTL_DISK_SET_PARTITION_INFO: |
| case IOCTL_DISK_VERIFY: |
| case IOCTL_SERIAL_LSRMST_INSERT: |
| case IOCTL_STORAGE_CHECK_VERIFY: |
| case IOCTL_STORAGE_EJECT_MEDIA: |
| case IOCTL_STORAGE_GET_MEDIA_TYPES: |
| case IOCTL_STORAGE_LOAD_MEDIA: |
| case IOCTL_STORAGE_MEDIA_REMOVAL: |
| FIXME( win32, "unimplemented dwIoControlCode=%08lx\n", dwIoControlCode); |
| SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); |
| return FALSE; |
| break; |
| default: |
| FIXME( win32, "ignored dwIoControlCode=%08lx\n",dwIoControlCode); |
| SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); |
| return FALSE; |
| break; |
| } |
| } |
| return FALSE; |
| } |