{code}
/*******************************************************************************

vdrive.c

Purpose: main source of Virtual Disk Drive

Author: SB, RSJ Software GmbH

Date: 10/2006

(c) Copyright 2006 by RSJ Software GmbH, Germering. All rights reserved.

*******************************************************************************/


/*------ includes ------------------------------------------------------------*/
#include <stdlib.h>
#include <windows.h>

#include "abstractvd.h"
#include "avdioctl.h"

/*------ typedefs ------------------------------------------------------------*/
/*******************************************************************************

VDRIVE_HANDLE

*******************************************************************************/
typedef struct {
AVD_HANDLE fileHandle;
UINT64 fileSize;
wchar_t fileName[_MAX_PATH+1];
} VDRIVE_HANDLE;


/*******************************************************************************

AvdOpen()

*******************************************************************************/
AVD_RET AVD_LINK AvdOpen(void *RequestContext,
void **ImplContext,
const wchar_t *Parms)
{
VDRIVE_HANDLE *vdhandle;
AVD_RET avd_ret;
wchar_t *cfsize;
UINT64 fsize;
wchar_t *fname_end;
size_t fname_len;
wchar_t *s;
wchar_t parm_copy[2 * _MAX_PATH + 1];

if (Parms == NULL || wcslen(Parms) > 2 * _MAX_PATH) {
return(AVD_INVALID_PARAMETER);
}

wcscpy(parm_copy, Parms);

fname_len = wcslen(parm_copy);

if (fname_len > _MAX_PATH) {
AvdDebugMessage(2, "AvdOpen(): Invalid Parms");
return(AVD_INVALID_PARAMETER);
}

if ((avd_ret = AvdMemoryAlloc(&vdhandle, sizeof(VDRIVE_HANDLE))) != AVD_OK) {
return(avd_ret);
}

wcscpy(vdhandle->fileName, parm_copy);

if ((avd_ret = AvdFileOpen(&vdhandle->fileHandle,
vdhandle->fileName)) != AVD_OK) {
AvdDebugMessage(2, "AvdFileOpen() returned %d\n", (int) avd_ret);
AvdMemoryFree(vdhandle);
return(avd_ret);
}

AvdFileSizeGet(vdhandle->fileHandle,
&(vdhandle->fileSize));

if ((avd_ret = AvdFileSizeSet(vdhandle->fileHandle,
vdhandle->fileSize)) != AVD_OK) {
AvdDebugMessage(2,
"AvdFileSizeSet (%d) returned %d\n",
(int) vdhandle->fileSize,
(int) avd_ret);
AvdFileClose(vdhandle->fileHandle);
AvdMemoryFree(vdhandle);
return(avd_ret);
}

*ImplContext = (void *) vdhandle;

return(AVD_OK);
}


/*******************************************************************************

AvdClose()

*******************************************************************************/
AVD_RET AVD_LINK AvdClose(void *RequestContext, void *ImplContext)
{
VDRIVE_HANDLE *vdhandle = (VDRIVE_HANDLE *) ImplContext;

if (vdhandle == NULL) {
return(AVD_INVALID_PARAMETER);
}

if (vdhandle->fileHandle) {
AvdFileClose(vdhandle->fileHandle);
}

AvdMemoryFree(vdhandle);

return(AVD_OK);
}


/*******************************************************************************

AvdGetMediaSize()

*******************************************************************************/
AVD_RET AVD_LINK AvdGetMediaSize(void *RequestContext,
void *ImplContext,
UINT64 *MediaSize,
unsigned short *SectorsPerTrack,
BOOLEAN *Writable)
{
VDRIVE_HANDLE *vdhandle = (VDRIVE_HANDLE *) ImplContext;

if (vdhandle == NULL ||
!vdhandle->fileHandle) {
return(AVD_INVALID_PARAMETER);
}

*MediaSize = vdhandle->fileSize;
*Writable = TRUE;
*SectorsPerTrack = 32;

return(AVD_OK);
}


/*******************************************************************************

AvdRead()

*******************************************************************************/
AVD_RET AVD_LINK AvdRead(void *RequestContext,
void *ImplContext,
unsigned char *Buffer,
UINT64 Offset,
size_t Length,
size_t *BytesRead)
{
VDRIVE_HANDLE *vdhandle = (VDRIVE_HANDLE *) ImplContext;

if (vdhandle == NULL ||
!vdhandle->fileHandle) {
return(AVD_INVALID_PARAMETER);
}

return(AvdFileRead(Buffer, vdhandle->fileHandle, Offset, Length, BytesRead));
}


/*******************************************************************************

AvdWrite()

*******************************************************************************/
AVD_RET AVD_LINK AvdWrite(void *RequestContext,
void *ImplContext,
unsigned char *Buffer,
UINT64 Offset,
size_t Length,
size_t *BytesWritten)
{
VDRIVE_HANDLE *vdhandle = (VDRIVE_HANDLE *) ImplContext;

if (vdhandle == NULL ||
!vdhandle->fileHandle) {
return(AVD_INVALID_PARAMETER);
}

return(AvdFileWrite(Buffer, vdhandle->fileHandle, Offset, Length, BytesWritten));
}


/*******************************************************************************

AvdCommmandInvoke()

*******************************************************************************/
AVD_RET AVD_LINK AvdCommandInvoke (void *RequestContext,
void *ImplContext,
void *Request,
size_t RequestLength,
void *Response,
size_t MaxResponseLen,
size_t *ActualResponseLen)
{
*ActualResponseLen = 0;

return(AVD_OK);
}
{code}