/* * Win32 device functions * * Copyright 1998 Marcus Meissner */ #include #include #include #include #include #include #include #include #include #include #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; }