Sweden-Number/win32/device.c

171 lines
4.4 KiB
C

/*
* 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;
}