/*
 *  sys_windows.cpp - System dependent routines, Windows implementation
 *
 *  Basilisk II (C) 1997-2008 Christian Bauer
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "sysdeps.h"

#include <winioctl.h>

#include <string>
typedef std::basic_string<TCHAR> tstring;

#include <algorithm>
using std::min;

#include "main.h"
#include "util_windows.h"
#include "macos_util.h"
#include "prefs.h"
#include "user_strings.h"
#include "sys.h"

#include "cd_defs.h"
#include "cdenable/ntcd.h"
#include "cdenable/cache.h"
#include "cdenable/eject_nt.h"

#define DEBUG 0
#include "debug.h"


// File handles are pointers to these structures
struct file_handle {
	TCHAR *name;		// Copy of device/file name
	HANDLE fh;
	bool is_file;		// Flag: plain file or physical device?
	bool is_floppy;		// Flag: floppy device
	bool is_cdrom;		// Flag: CD-ROM device
	bool read_only;		// Copy of Sys_open() flag
	loff_t start_byte;	// Size of file header (if any)
	loff_t file_size;	// Size of file data (only valid if is_file is true)
	cachetype cache;
	bool is_media_present;
};

// Open file handles
struct open_file_handle {
	file_handle *fh;
	open_file_handle *next;
};
static open_file_handle *open_file_handles = NULL;

// File handle of first floppy drive (for SysMountFirstFloppy())
static file_handle *first_floppy = NULL;

// CD-ROM variables
static const int CD_READ_AHEAD_SECTORS = 16;
static char *sector_buffer = NULL;

// Prototypes
static bool is_cdrom_readable(file_handle *fh);


/*
 *  Initialization
 */

void SysInit(void)
{
	// Initialize CD-ROM driver
	sector_buffer = (char *)VirtualAlloc(NULL, 8192, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
	CdenableSysInstallStart();
}


/*
 *  Deinitialization
 */

void SysExit(void)
{
	if (sector_buffer) {
		VirtualFree(sector_buffer, 0, MEM_RELEASE );
		sector_buffer = NULL;
	}
}


/*
 *  Manage open file handles
 */

static void sys_add_file_handle(file_handle *fh)
{
	open_file_handle *p = new open_file_handle;
	p->fh = fh;
	p->next = open_file_handles;
	open_file_handles = p;
}

static void sys_remove_file_handle(file_handle *fh)
{
	open_file_handle *p = open_file_handles;
	open_file_handle *q = NULL;

	while (p) {
		if (p->fh == fh) {
			if (q)
				q->next = p->next;
			else
				open_file_handles = p->next;
			delete p;
			break;
		}
		q = p;
		p = p->next;
	}
}


/*
 *  Mount removable media now
 */

void mount_removable_media(int media)
{
	for (open_file_handle *p = open_file_handles; p != NULL; p = p->next) {
		file_handle * const fh = p->fh;

		if (fh->is_cdrom && (media & MEDIA_CD)) {
			cache_clear(&fh->cache);
			fh->start_byte = 0;

			if (fh->fh && fh->fh != INVALID_HANDLE_VALUE)
				CloseHandle(fh->fh);

			// Re-open device
			TCHAR device_name[MAX_PATH];
			_sntprintf(device_name, lengthof(device_name), TEXT("\\\\.\\%c:"), fh->name[0]);
			fh->fh = CreateFile(
				device_name,
				GENERIC_READ,
				FILE_SHARE_READ | FILE_SHARE_WRITE,
				NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

			if (fh->fh != INVALID_HANDLE_VALUE) {
				fh->is_media_present = is_cdrom_readable(fh);
				if (fh->is_media_present)
					MountVolume(fh);
			} else {
				fh->is_media_present = false;
			}
		}
	}
}


/*
 *  Account for media that has just arrived
 */

void SysMediaArrived(void)
{
	mount_removable_media(MEDIA_REMOVABLE);
}


/*
 *  Account for media that has just been removed
 */

void SysMediaRemoved(void)
{
}


/*
 *  Mount first floppy disk
 */

void SysMountFirstFloppy(void)
{
	if (first_floppy)
		MountVolume(first_floppy);
}


/*
 *  This gets called when no "floppy" prefs items are found
 *  It scans for available floppy drives and adds appropriate prefs items
 */

void SysAddFloppyPrefs(void)
{
}


/*
 *  This gets called when no "disk" prefs items are found
 *  It scans for available HFS volumes and adds appropriate prefs items
 */

void SysAddDiskPrefs(void)
{
}


/*
 *  This gets called when no "cdrom" prefs items are found
 *  It scans for available CD-ROM drives and adds appropriate prefs items
 */

void SysAddCDROMPrefs(void)
{
	// Don't scan for drives if nocdrom option given
	if (PrefsFindBool("nocdrom"))
		return;

	char rootdir[] = "C:\\";
	for (; rootdir[0] <= 'Z'; rootdir[0]++) {
		if (GetDriveTypeA(rootdir) == DRIVE_CDROM)
			PrefsAddString("cdrom", rootdir);
	}
}


/*
 *  Add default serial prefs (must be added, even if no ports present)
 */

void SysAddSerialPrefs(void)
{
	PrefsAddString("seriala", "COM1");
	PrefsAddString("serialb", "COM2");
}


/*
 *  Read CD-ROM
 *  Must give cd some time to settle
 *  Can't give too much however, would be annoying, this is difficult..
 */

static inline int cd_read_with_retry(file_handle *fh, ULONG LBA, int count, char *buf )
{
	if (!fh || !fh->fh)
		return 0;

	return CdenableSysReadCdBytes(fh->fh, LBA, count, buf);
}

static int cd_read(file_handle *fh, cachetype *cptr, ULONG LBA, int count, char *buf)
{
	ULONG l1, l2, cc;
	int i, c_count, got_bytes = 0, nblocks, s_inx, ss, first_block;
	int ok_bytes = 0;
	char *ptr, *ttptr = 0, *tmpbuf;

	if (count <= 0)
		return 0;

	if (!fh || !fh->fh)
		return 0;

	ss = 2048;
	l1 = (LBA / ss) * ss;
	l2 = ((LBA + count - 1 + ss) / ss) * ss;
	cc = l2 - l1;
	nblocks = cc / ss;
	first_block = LBA / ss;

	ptr = buf;
	s_inx = LBA - l1;
	c_count = ss - s_inx;
	if (c_count > count)
		c_count = count;

	for (i = 0; i < nblocks; i++) {
		if (!cache_get(cptr, first_block + i, sector_buffer))
			break;

		memcpy(ptr, sector_buffer + s_inx, c_count);
		ok_bytes += c_count;
		ptr += c_count;
		s_inx = 0;
		c_count = ss;
		if (c_count > count - ok_bytes)
			c_count = count - ok_bytes;
	}

	if (i != nblocks && count != ok_bytes) {
		int bytes_left = count - ok_bytes;
		int blocks_left = nblocks - i;
		int alignedleft;

		// NEW read ahead code:
		int ahead = CD_READ_AHEAD_SECTORS;
		if (blocks_left < ahead) {
			nblocks += (ahead - blocks_left);
			blocks_left = ahead;
		}

		alignedleft = blocks_left*ss;

		tmpbuf = (char *)VirtualAlloc(
			NULL, alignedleft,
			MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
		if (tmpbuf) {
			got_bytes = cd_read_with_retry(fh, (first_block + i) * ss, alignedleft, tmpbuf);
			if (got_bytes != alignedleft) {
				// should never happen
				// Yes it does ...
				if (got_bytes < 0)
					got_bytes = 0;
				if (c_count > got_bytes)
					c_count = got_bytes;
				if (c_count > 0) {
					ttptr = tmpbuf;
					memcpy(ptr, ttptr + s_inx, c_count);
					ok_bytes += c_count;
				}
				VirtualFree(tmpbuf, 0, MEM_RELEASE );
				return ok_bytes;
			}
			ttptr = tmpbuf;
			for ( ; i < nblocks; i++) {
				if (c_count > 0) {
					memcpy(ptr, ttptr + s_inx, c_count);
					ok_bytes += c_count;
					ptr += c_count;
				}
				s_inx = 0;
				c_count = ss;
				if (c_count > count - ok_bytes)
					c_count = count - ok_bytes;
				cache_put(cptr, first_block + i, ttptr, ss);
				ttptr += ss;
			}
			VirtualFree(tmpbuf, 0, MEM_RELEASE );
		}
	}

	return ok_bytes;
}


/*
 *  Check if file handle FH represents a readable CD-ROM
 */

static bool is_cdrom_readable(file_handle *fh)
{
	if (!fh || !fh->fh)
		return false;

	cache_clear(&fh->cache);

	DWORD dummy;
	bool result = (0 != DeviceIoControl(
		fh->fh,
		IOCTL_STORAGE_CHECK_VERIFY,
		NULL, 0,
		NULL, 0,
		&dummy,
		NULL));
	if (!result) {
		const size_t n_bytes = 2048;
		char *buffer = (char *)VirtualAlloc(NULL, n_bytes, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
		if (buffer) {
			result = (cd_read_with_retry(fh, 0, n_bytes, buffer) == n_bytes);
			VirtualFree(buffer, 0, MEM_RELEASE);
		}
	}

	return result;
}


/*
 *  Check if NAME represents a read-only file
 */

static bool is_read_only_path(const TCHAR *name)
{
	DWORD attrib = GetFileAttributes(name);
	return (attrib != INVALID_FILE_ATTRIBUTES && ((attrib & FILE_ATTRIBUTE_READONLY) != 0));
}


/*
 *  Open file/device, create new file handle (returns NULL on error)
 */

void *Sys_open(const char *path_name, bool read_only)
{
	file_handle * fh = NULL;

	// Parse path name and options
	TCHAR name[MAX_PATH];
	tcslcpy(name, path_name, lengthof(name));

	// Normalize floppy / cd path
	int name_len = _tcslen(name);
	if (name_len == 1 && _istalpha(name[0]))
		_tcscat(name, TEXT(":\\"));
	if (name_len > 0 && name[name_len - 1] == TEXT(':'))
		_tcscat(name, TEXT("\\"));
	name_len = _tcslen(name);

	D(bug(TEXT("Sys_open(%s, %s)\n"), name, read_only ? TEXT("read-only") : TEXT("read/write")));
	if (name_len > 0 && name[name_len - 1] == TEXT('\\')) {
		int type = GetDriveType(name);

		if (type == DRIVE_CDROM) {
			read_only = true;
			TCHAR device_name[MAX_PATH];
			_sntprintf(device_name, lengthof(device_name), TEXT("\\\\.\\%c:"), name[0]);

			// Open device
			HANDLE h = CreateFile(
				device_name,
				GENERIC_READ,
				0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

			if (h != INVALID_HANDLE_VALUE) {
				fh = new file_handle;
				fh->name = _tcsdup(name);
				fh->fh = h;
				fh->is_file = false;
				fh->read_only = read_only;
				fh->start_byte = 0;
				fh->is_floppy = false;
				fh->is_cdrom = true;
				memset(&fh->cache, 0, sizeof(cachetype));
				cache_init(&fh->cache);
				cache_clear(&fh->cache);
				if (!PrefsFindBool("nocdrom"))
					fh->is_media_present = is_cdrom_readable(fh);
			}
		}
	}

	else { // Hard file

		// Check if write access is allowed, set read-only flag if not
		if (!read_only && is_read_only_path(name))
			read_only = true;

		// Open file
		HANDLE h = CreateFile(
			name,
			read_only ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
			0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

		if (h == INVALID_HANDLE_VALUE && !read_only) {
			// Read-write failed, try read-only
			read_only = true;
			h = CreateFile(
				name,
				GENERIC_READ,
				0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
		}

		if (h != INVALID_HANDLE_VALUE) {
			fh = new file_handle;
			fh->name = _tcsdup(name);
			fh->fh = h;
			fh->is_file = true;
			fh->read_only = read_only;
			fh->start_byte = 0;
			fh->is_floppy = false;
			fh->is_cdrom = false;

			// Detect disk image file layout
			loff_t size = GetFileSize(h, NULL);
			DWORD bytes_read;
			uint8 data[256];
			ReadFile(h, data, sizeof(data), &bytes_read, NULL);
			FileDiskLayout(size, data, fh->start_byte, fh->file_size);
		}
	}

	if (fh) {
		if (fh->is_floppy && first_floppy == NULL)
			first_floppy = fh;
		sys_add_file_handle(fh);
	}

	return fh;
}


/*
 *  Close file/device, delete file handle
 */

void Sys_close(void *arg)
{
	file_handle *fh = (file_handle *)arg;
	if (!fh)
		return;

	sys_remove_file_handle(fh);

	if (fh->is_cdrom) {
		cache_final(&fh->cache);
		SysAllowRemoval((void *)fh);
	}
	if (fh->fh != NULL) {
		CloseHandle(fh->fh);
		fh->fh = NULL;
	}
	if (fh->name)
		free(fh->name);

	delete fh;
}


/*
 *  Read "length" bytes from file/device, starting at "offset", to "buffer",
 *  returns number of bytes read (or 0)
 */

size_t Sys_read(void *arg, void *buffer, loff_t offset, size_t length)
{
	file_handle *fh = (file_handle *)arg;
	if (!fh)
		return 0;

	DWORD bytes_read = 0;

	if (fh->is_file) {
		// Seek to position
		LONG lo = (LONG)offset;
		LONG hi = (LONG)(offset >> 32);
		DWORD r = SetFilePointer(fh->fh, lo, &hi, FILE_BEGIN);
		if (r == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
			return 0;

		// Read data
		if (ReadFile(fh->fh, buffer, length, &bytes_read, NULL) == 0)
			bytes_read = 0;
	}
	else if (fh->is_cdrom) {
		int bytes_left, try_bytes, got_bytes;
		char *b = (char *)buffer;
		bytes_left = length;
		while (bytes_left) {
			try_bytes = min(bytes_left, 32768);
			if (fh->is_cdrom) {
				got_bytes = cd_read(fh, &fh->cache, (DWORD)offset, try_bytes, b);
				if (got_bytes != try_bytes && !PrefsFindBool("nocdrom"))
					fh->is_media_present = is_cdrom_readable(fh);
			}
			b += got_bytes;
			offset += got_bytes;
			bytes_read += got_bytes;
			bytes_left -= got_bytes;
			if (got_bytes != try_bytes)
				bytes_left = 0;
		}
	}
	// TODO: other media

	return bytes_read;
}


/*
 *  Write "length" bytes from "buffer" to file/device, starting at "offset",
 *  returns number of bytes written (or 0)
 */

size_t Sys_write(void *arg, void *buffer, loff_t offset, size_t length)
{
	file_handle *fh = (file_handle *)arg;
	if (!fh)
		return 0;

	DWORD bytes_written = 0;

	if (fh->is_file) {
		// Seek to position
		LONG lo = (LONG)offset;
		LONG hi = (LONG)(offset >> 32);
		DWORD r = SetFilePointer(fh->fh, lo, &hi, FILE_BEGIN);
		if (r == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
			return 0;

		// Write data
		if (WriteFile(fh->fh, buffer, length, &bytes_written, NULL) == 0)
			bytes_written = 0;
	}
	// TODO: other media

	return bytes_written;
}


/*
 *  Return size of file/device (minus header)
 */

loff_t SysGetFileSize(void *arg)
{
	file_handle *fh = (file_handle *)arg;
	if (!fh)
		return true;

	if (fh->is_file)
		return fh->file_size;
	else if (fh->is_cdrom)
		return 0x28A00000; // FIXME: get real CD-ROM size
	else {
		// TODO: other media
		return 0;
	}
}


/*
 *  Eject volume (if applicable)
 */

void SysEject(void *arg)
{
	file_handle *fh = (file_handle *)arg;
	if (!fh)
		return;

	if (fh->is_cdrom && fh->fh) {
		fh->is_media_present = false;
		// Commented out because there was some problems, but can't remember
		// exactly ... need to find out
		// EjectVolume(toupper(*fh->name),false);

		// Preventing is cumulative, try to make sure it's indeed released now
		for (int i = 0; i < 10; i++)
			PreventRemovalOfVolume(fh->fh, false);

		if (!PrefsFindBool("nocdrom")) {
			DWORD dummy;
			DeviceIoControl(
				fh->fh,
				IOCTL_STORAGE_EJECT_MEDIA,
				NULL, 0,
				NULL, 0,
				&dummy,
				NULL
				);
		}
		cache_clear(&fh->cache);
		fh->start_byte = 0;
	}
	// TODO: handle floppies
}


/*
 *  Format volume (if applicable)
 */

bool SysFormat(void *arg)
{
	file_handle *fh = (file_handle *)arg;
	if (!fh)
		return false;

	//!!
	return true;
}


/*
 *  Check if file/device is read-only (this includes the read-only flag on Sys_open())
 */

bool SysIsReadOnly(void *arg)
{
	file_handle *fh = (file_handle *)arg;
	if (!fh)
		return true;

	return fh->read_only;
}


/*
 *  Check if the given file handle refers to a fixed or a removable disk
 */

bool SysIsFixedDisk(void *arg)
{
	file_handle *fh = (file_handle *)arg;
	if (!fh)
		return true;

	if (fh->is_file)
		return true;
	else if (fh->is_floppy || fh->is_cdrom)
		return false;
	else
		return true;
}


/*
 *  Check if a disk is inserted in the drive (always true for files)
 */

bool SysIsDiskInserted(void *arg)
{
	file_handle *fh = (file_handle *)arg;
	if (!fh)
		return false;

	if (fh->is_file)
		return true;
	else if (fh->is_cdrom && !PrefsFindBool("nocdrom")) {
		if (PrefsFindBool("pollmedia"))
			fh->is_media_present = is_cdrom_readable(fh);
		return fh->is_media_present;
	}
	else {
		// TODO: other media
	}

	return false;
}


/*
 *  Prevent medium removal (if applicable)
 */

void SysPreventRemoval(void *arg)
{
	file_handle *fh = (file_handle *)arg;
	if (!fh)
		return;

	if (fh->is_cdrom && fh->fh)
		PreventRemovalOfVolume(fh->fh, true);
}


/*
 *  Allow medium removal (if applicable)
 */

void SysAllowRemoval(void *arg)
{
	file_handle *fh = (file_handle *)arg;
	if (!fh)
		return;

	if (fh->is_cdrom && fh->fh)
		PreventRemovalOfVolume(fh->fh, false);
}


/*
 *  Read CD-ROM TOC (binary MSF format, 804 bytes max.)
 */

bool SysCDReadTOC(void *arg, uint8 *toc)
{
	file_handle *fh = (file_handle *)arg;
	if (!fh || !fh->fh || !fh->is_cdrom)
		return false;

	DWORD dummy;
	return DeviceIoControl(fh->fh,
						   IOCTL_CDROM_READ_TOC,
						   NULL, 0,
						   toc, min((int)sizeof(CDROM_TOC), 804),
						   &dummy,
						   NULL) != FALSE;
}


/*
 *  Read CD-ROM position data (Sub-Q Channel, 16 bytes, see SCSI standard)
 */

bool SysCDGetPosition(void *arg, uint8 *pos)
{
	file_handle *fh = (file_handle *)arg;
	if (!fh || !fh->fh || !fh->is_cdrom)
		return false;

	SUB_Q_CHANNEL_DATA q_data;

	CDROM_SUB_Q_DATA_FORMAT q_format;
	q_format.Format = IOCTL_CDROM_CURRENT_POSITION;
	q_format.Track = 0; // used only by ISRC reads

	DWORD dwBytesReturned = 0;
	bool ok = DeviceIoControl(fh->fh,
							  IOCTL_CDROM_READ_Q_CHANNEL,
							  &q_format, sizeof(CDROM_SUB_Q_DATA_FORMAT),
							  &q_data, sizeof(SUB_Q_CHANNEL_DATA),
							  &dwBytesReturned,
							  NULL) != FALSE;
	if (ok)
		memcpy(pos, &q_data.CurrentPosition, sizeof(SUB_Q_CURRENT_POSITION));

	return ok;
}


/*
 *  Play CD audio
 */

bool SysCDPlay(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, uint8 end_m, uint8 end_s, uint8 end_f)
{
	file_handle *fh = (file_handle *)arg;
	if (!fh || !fh->fh || !fh->is_cdrom)
		return false;

	CDROM_PLAY_AUDIO_MSF msf;
	msf.StartingM = start_m;
	msf.StartingS = start_s;
	msf.StartingF = start_f;
	msf.EndingM = end_m;
	msf.EndingS = end_s;
	msf.EndingF = end_f;

	DWORD dwBytesReturned = 0;
	return DeviceIoControl(fh->fh,
						   IOCTL_CDROM_PLAY_AUDIO_MSF,
						   &msf, sizeof(CDROM_PLAY_AUDIO_MSF),
						   NULL, 0,
						   &dwBytesReturned,
						   NULL) != FALSE;
}


/*
 *  Pause CD audio
 */

bool SysCDPause(void *arg)
{
	file_handle *fh = (file_handle *)arg;
	if (!fh || !fh->fh || !fh->is_cdrom)
		return false;

	DWORD dwBytesReturned = 0;
	return DeviceIoControl(fh->fh,
						   IOCTL_CDROM_PAUSE_AUDIO,
						   NULL, 0,
						   NULL, 0,
						   &dwBytesReturned,
						   NULL) != FALSE;
}


/*
 *  Resume paused CD audio
 */

bool SysCDResume(void *arg)
{
	file_handle *fh = (file_handle *)arg;
	if (!fh || !fh->fh || !fh->is_cdrom)
		return false;

	DWORD dwBytesReturned = 0;
	return DeviceIoControl(fh->fh,
						   IOCTL_CDROM_RESUME_AUDIO,
						   NULL, 0,
						   NULL, 0,
						   &dwBytesReturned, NULL) != FALSE;
}


/*
 *  Stop CD audio
 */

bool SysCDStop(void *arg, uint8 lead_out_m, uint8 lead_out_s, uint8 lead_out_f)
{
	file_handle *fh = (file_handle *)arg;
	if (!fh || !fh->fh || !fh->is_cdrom)
		return false;

	DWORD dwBytesReturned = 0;
	return DeviceIoControl(fh->fh,
						   IOCTL_CDROM_STOP_AUDIO,
						   NULL, 0,
						   NULL, 0,
						   &dwBytesReturned,
						   NULL) != FALSE;
}


/*
 *  Perform CD audio fast-forward/fast-reverse operation starting from specified address
 */

bool SysCDScan(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, bool reverse)
{
	file_handle *fh = (file_handle *)arg;
	if (!fh || !fh->fh || !fh->is_cdrom)
		return false;

	CDROM_SEEK_AUDIO_MSF msf;
	msf.M = start_m;
	msf.S = start_s;
	msf.F = start_f;

	DWORD dwBytesReturned = 0;
	return DeviceIoControl(fh->fh,
						   IOCTL_CDROM_SEEK_AUDIO_MSF,
						   &msf, sizeof(CDROM_SEEK_AUDIO_MSF),
						   NULL, 0,
						   &dwBytesReturned,
						   NULL) != FALSE;
}


/*
 *  Set CD audio volume (0..255 each channel)
 */

void SysCDSetVolume(void *arg, uint8 left, uint8 right)
{
	file_handle *fh = (file_handle *)arg;
	if (!fh || !fh->fh || !fh->is_cdrom)
		return;

	VOLUME_CONTROL vc;
	vc.PortVolume[0] = left;
	vc.PortVolume[1] = right;
	vc.PortVolume[2] = left;
	vc.PortVolume[3] = right;

	DWORD dwBytesReturned = 0;
	DeviceIoControl(fh->fh,
					IOCTL_CDROM_SET_VOLUME,
					&vc, sizeof(VOLUME_CONTROL),
					NULL, 0,
					&dwBytesReturned,
					NULL);
}


/*
 *  Get CD audio volume (0..255 each channel)
 */

void SysCDGetVolume(void *arg, uint8 &left, uint8 &right)
{
	file_handle *fh = (file_handle *)arg;
	if (!fh)
		return;

	left = right = 0;
	if (!fh->fh || !fh->is_cdrom)
		return;

	VOLUME_CONTROL vc;
	memset(&vc, 0, sizeof(vc));

	DWORD dwBytesReturned = 0;
	if (DeviceIoControl(fh->fh,
						IOCTL_CDROM_GET_VOLUME,
						NULL, 0,
						&vc, sizeof(VOLUME_CONTROL),
						&dwBytesReturned,
						NULL))
	{
		left = vc.PortVolume[0];
		right = vc.PortVolume[1];
	}
}
