aboutsummaryrefslogtreecommitdiff
path: root/Src/burnlib
diff options
context:
space:
mode:
Diffstat (limited to 'Src/burnlib')
-rw-r--r--Src/burnlib/api.h8
-rw-r--r--Src/burnlib/burnlib.h18
-rw-r--r--Src/burnlib/burnlib.rc1092
-rw-r--r--Src/burnlib/burnlib.sln67
-rw-r--r--Src/burnlib/burnlib.vcproj284
-rw-r--r--Src/burnlib/common.cpp261
-rw-r--r--Src/burnlib/eraseMedium.cpp183
-rw-r--r--Src/burnlib/eraseMedium.h68
-rw-r--r--Src/burnlib/item.cpp252
-rw-r--r--Src/burnlib/item.h105
-rw-r--r--Src/burnlib/main.cpp24
-rw-r--r--Src/burnlib/main.h30
-rw-r--r--Src/burnlib/manager.h42
-rw-r--r--Src/burnlib/playlist.cpp686
-rw-r--r--Src/burnlib/playlist.h157
-rw-r--r--Src/burnlib/primosdk.h53
-rw-r--r--Src/burnlib/resdll/resdll.vcproj225
-rw-r--r--Src/burnlib/resource.h650
-rw-r--r--Src/burnlib/resources/disc1.bmpbin0 -> 30158 bytes
-rw-r--r--Src/burnlib/resources/drive1.bmpbin0 -> 6862 bytes
-rw-r--r--Src/burnlib/resources/testmode.bmpbin0 -> 2394 bytes
-rw-r--r--Src/burnlib/uiBurnPlayList.cpp1345
-rw-r--r--Src/burnlib/uiBurnPlaylist.h133
-rw-r--r--Src/burnlib/uiCheckMedium.cpp300
-rw-r--r--Src/burnlib/uiCheckMedium.h55
-rw-r--r--Src/burnlib/uiEraseMedium.cpp340
-rw-r--r--Src/burnlib/uiEraseMedium.h51
-rw-r--r--Src/burnlib/uiUnitReady.cpp230
-rw-r--r--Src/burnlib/uiUnitReady.h47
-rw-r--r--Src/burnlib/uiUpdatingData.cpp206
-rw-r--r--Src/burnlib/uiUpdatingData.h40
-rw-r--r--Src/burnlib/unitStatusText.cpp996
32 files changed, 7948 insertions, 0 deletions
diff --git a/Src/burnlib/api.h b/Src/burnlib/api.h
new file mode 100644
index 00000000..f6387c90
--- /dev/null
+++ b/Src/burnlib/api.h
@@ -0,0 +1,8 @@
+#ifndef __WASABI_API_H
+#define __WASABI_API_H
+
+#include <api/service/api_service.h>
+extern api_service *serviceManager;
+#define WASABI_API_SVC serviceManager
+
+#endif
diff --git a/Src/burnlib/burnlib.h b/Src/burnlib/burnlib.h
new file mode 100644
index 00000000..b32e2a8e
--- /dev/null
+++ b/Src/burnlib/burnlib.h
@@ -0,0 +1,18 @@
+#ifndef NULLSOFT_BURN_LIBRARY_HEADER
+#define NULLSOFT_BURN_LIBRARY_HEADER
+
+#include "./main.h"
+
+#include "./item.h"
+#include "./playlist.h"
+#include "./eraseMedium.h"
+
+#include "./uiUpdatingData.h"
+#include "./uiUnitReady.h"
+#include "./uiCheckMedium.h"
+
+#include "./uiEraseMedium.h"
+#include "./uiBurnPlaylist.h"
+
+
+#endif //NULLSOFT_BURN_LIBRARY_HEADER \ No newline at end of file
diff --git a/Src/burnlib/burnlib.rc b/Src/burnlib/burnlib.rc
new file mode 100644
index 00000000..e5e2e47f
--- /dev/null
+++ b/Src/burnlib/burnlib.rc
@@ -0,0 +1,1092 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DLG_UNITNOTREADY DIALOGEX 0, 0, 235, 73
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_NOFAILCREATE | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_NOPARENTNOTIFY
+CAPTION "Nullsoft Burner"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL 106,IDC_PIC,"Static",SS_BITMAP,7,7,33,28
+ LTEXT "Drive G: is not ready.",IDC_CAPTION,45,7,186,9
+ LTEXT "Reason:",IDC_LBL_REASON,45,19,28,8
+ LTEXT "string 1\nstring 2",IDC_LBL_REASON_VAL,74,19,157,18
+ LTEXT "Please insert proper disc and close tray or click 'Cancel' to abort operation.",IDC_LBL_HELP,45,37,186,17
+ DEFPUSHBUTTON "Retry",IDOK,119,55,50,14,NOT WS_VISIBLE
+ PUSHBUTTON "Cancel",IDCANCEL,181,55,50,14
+END
+
+IDD_DLG_WRONGMEDIUM DIALOGEX 0, 0, 267, 177
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "Nullsoft Burner - Wrong Media"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LTEXT "Drive G: contains wrong media type.",IDC_CAPTION,3,7,260,15,SS_CENTERIMAGE,WS_EX_STATICEDGE
+ CONTROL 107,IDC_PIC,"Static",SS_BITMAP,3,26,47,87
+ GROUPBOX "Required",IDC_STATIC,55,25,208,33
+ LTEXT "string 1\nstring 2",IDC_LBL_REQUESTEDMEDIUM,60,35,199,18
+ GROUPBOX "Detected",IDC_STATIC,55,63,208,78
+ LTEXT "string 1\nstring 2\nstring 3\nstring 4\nstring 5\nstring 6\nstring 7\nstring 8",IDC_LBL_DETECTEDMEDIUM,60,73,199,64
+ PUSHBUTTON "Erase\r\nthis disc",IDC_BTN_ERASE,3,120,47,22,BS_CENTER | BS_VCENTER | BS_MULTILINE
+ CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,3,150,260,1
+ DEFPUSHBUTTON "Check again",IDOK,144,156,64,14
+ PUSHBUTTON "Cancel",IDCANCEL,213,156,50,14
+END
+
+IDD_DLG_ERASEMEDIUMSTATUS DIALOGEX 0, 0, 219, 60
+STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "Nullsoft Disc Eraser"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LTEXT "Erasing...",IDC_LBL_STATUS,7,7,133,8
+ RTEXT "00:00 / 01:45",IDC_LBL_TIME,145,7,66,10
+ CONTROL "",IDC_PRG_PROGRESS,"msctls_progress32",WS_BORDER,7,17,204,14
+ CONTROL "Eject when done (recommended).",IDC_BTN_EJECT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,43,119,10
+ PUSHBUTTON "Cancel",IDCANCEL,161,39,50,14
+END
+
+IDD_DLG_ERASEMEDIUMPREPARE DIALOGEX 0, 0, 209, 90
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "Nullsoft Disc Eraser"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LTEXT "Plese select erasing method for disc in drive G:",IDC_CAPTION,7,7,195,8
+ LTEXT "Erase method:",IDC_STATIC,7,29,57,8
+ COMBOBOX IDC_CMB_ERASEMETHOD,61,27,141,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "Estimated time:",IDC_STATIC,7,47,57,8
+ LTEXT "00:02:15",IDC_LBL_TIME,61,47,141,8
+ CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,7,64,195,1
+ DEFPUSHBUTTON "OK",IDOK,94,69,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,152,69,50,14
+END
+
+IDD_DLG_UPDATING DIALOGEX 0, 0, 183, 35
+STYLE DS_SETFONT | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION
+EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW
+CAPTION "Nullsoft Burner"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LTEXT "Updating data...",IDC_LBL_TEXT,7,6,169,8
+END
+
+IDD_DLG_BURNER DIALOGEX 0, 0, 298, 234
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_NOFAILCREATE | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "Winamp Burner - Audio CD "
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LTEXT "Burning Audio disc in drive G:",IDC_LBL_CAPTION,7,7,241,9
+ RTEXT "20%",IDC_LBL_PERCENT,267,7,24,8
+ CONTROL "",IDC_PRG_TOTAL,"msctls_progress32",WS_BORDER,7,16,284,14
+ LTEXT "Currently:",IDC_LBL_CURRENTOPERATION,7,33,41,9
+ CONTROL "Preparing data... (1 of 10 completed)",IDC_LBL_CURRENTOPERATION_VAL,
+ "Static",SS_LEFTNOWORDWRAP | SS_NOPREFIX | SS_ENDELLIPSIS | WS_GROUP,43,33,206,8
+ CONTROL 109,IDC_PIC_TESTMODE,"Static",SS_BITMAP | SS_REALSIZEIMAGE,252,32,39,8
+ LTEXT "Elapsed time:",IDC_LBL_ELAPSED,7,46,55,8
+ LTEXT "00:01:46",IDC_LBL_ELAPSED_VAL,62,46,32,8
+ LTEXT "Estimated time:",IDC_LBL_ESTIMATED,7,56,55,8
+ LTEXT "00:10:12",IDC_LBL_ESTIMATED_VAL,62,56,32,8
+ PUSHBUTTON "Continue Anyway",IDC_BTN_CONTINUE,113,51,66,14,NOT WS_VISIBLE
+ PUSHBUTTON "Show More",IDC_BTN_EXTENDEDVIEW,187,51,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,241,51,50,14
+ CONTROL "",IDC_LST_DETAILS,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,7,73,284,113
+ GROUPBOX "Options",IDC_GRP_OPTIONS,7,188,284,39
+ CONTROL "Close this window when done.",IDC_CHK_AUTOCLOSE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,200,120,8
+ CONTROL "Eject CD when done.",IDC_CHK_EJECT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,212,120,8
+ CONTROL "Remember this compilation.",IDC_CHK_ADDTODB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,162,200,122,8
+ CONTROL "Hide this window.",IDC_CHK_HIDEWINDOW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,162,212,122,8
+END
+
+IDD_DLG_COMPILATION DIALOGEX 0, 0, 221, 105
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Winamp Compilation Info"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,105,84,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,164,84,50,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_DLG_UNITNOTREADY, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 231
+ VERTGUIDE, 45
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 69
+ END
+
+ IDD_DLG_WRONGMEDIUM, DIALOG
+ BEGIN
+ LEFTMARGIN, 3
+ RIGHTMARGIN, 263
+ VERTGUIDE, 49
+ VERTGUIDE, 55
+ VERTGUIDE, 60
+ VERTGUIDE, 259
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 170
+ END
+
+ IDD_DLG_ERASEMEDIUMSTATUS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 211
+ TOPMARGIN, 8
+ BOTTOMMARGIN, 53
+ END
+
+ IDD_DLG_ERASEMEDIUMPREPARE, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 202
+ VERTGUIDE, 61
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 83
+ END
+
+ IDD_DLG_UPDATING, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 176
+ TOPMARGIN, 6
+ BOTTOMMARGIN, 29
+ END
+
+ IDD_DLG_BURNER, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 291
+ VERTGUIDE, 12
+ VERTGUIDE, 62
+ VERTGUIDE, 132
+ VERTGUIDE, 162
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 227
+ END
+
+ IDD_DLG_COMPILATION, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 214
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 98
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDB_DRIVE1 BITMAP ".\\resources\\drive1.bmp"
+IDB_DISC1 BITMAP ".\\resources\\disc1.bmp"
+IDB_TESTMODE BITMAP "resources\\testmode.bmp"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 5,8,0,0
+ PRODUCTVERSION 5,8,0,0
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Winamp SA"
+ VALUE "FileDescription", "Winamp Support Library"
+ VALUE "FileVersion", "5, 8, 0, 0"
+ VALUE "InternalName", "burnlib.dll"
+ VALUE "LegalCopyright", "Copyright © 2003-2019 Winamp SA"
+ VALUE "OriginalFilename", "burnlib.dll"
+ VALUE "ProductName", "Winamp CD Rip & Burn Resources"
+ VALUE "ProductVersion", "5, 8, 0, 0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDS_MEDIUM_BDR "Write-Once BD disc"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_COLUMN_TITLE "Title"
+ IDS_COLUMN_DURATION "Duration"
+ IDS_COLUMN_STATUS "Status"
+ IDS_COLUMN_FILE "File"
+ IDS_OK "Ok"
+ IDS_CANCEL "Cancel"
+ IDS_STOP "Stop"
+ IDS_CLOSE "Close"
+ IDS_UNKNOWN "Unknown"
+ IDS_YES "Yes"
+ IDS_NO "No"
+ IDS_MEDIUM_CD "CD-ROM"
+ IDS_MEDIUM_CDR "CD-R"
+ IDS_MEDIUM_CDRW "CD-RW"
+ IDS_MEDIUM_DVD "DVD-ROM"
+ IDS_MEDIUM_DVDR "DVD-R"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_MEDIUM_DVDRW "DVD-RW"
+ IDS_MEDIUM_DVDPR "DVD+R"
+ IDS_MEDIUM_DVDPRW "DVD+RW"
+ IDS_MEDIUM_DVDRAM "DVD-RAM"
+ IDS_MEDIUM_DDCD "DDCD-ROM"
+ IDS_MEDIUM_DDCDR "DDCD-R"
+ IDS_MEDIUM_DDCDRW "DDCD-RW"
+ IDS_MEDIUM_DVDPR9 "DL DVD+R"
+ IDS_MEDIUM_DVDR9 "DL DVD-R"
+ IDS_MEDIUM_BDRE "Rewritable BD disc"
+ IDS_MEDIUMTYPE_SILVER "Stamped disc or a recordable disc that has been recorded Disc-At-Once"
+ IDS_MEDIUMTYPE_COMPILATIONGOLD
+ "Recordable or rewritable disc that contains data but remains open, allowing the appending of additional data"
+ IDS_MEDIUMTYPE_OTHERGOLD
+ "Recordable disc to which is not possible to append additional data"
+ IDS_MEDIUMTYPE_BLANK "Blank recordable or rewritable disc"
+ IDS_MEDIUMFORMAT_B1 "Blank disc"
+ IDS_MEDIUMFORMAT_D1 "Data Mode 1 (Disc At Once)"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_MEDIUMFORMAT_D2 "Kodak Photo CD"
+ IDS_MEDIUMFORMAT_D3 "Data multisession Mode 1 (closed recordable disc)"
+ IDS_MEDIUMFORMAT_D4 "Data multisession Mode 2 (closed recordable disc)"
+ IDS_MEDIUMFORMAT_D5 "Data Mode 2 (Disc At Once)"
+ IDS_MEDIUMFORMAT_D6 "CDRFS"
+ IDS_MEDIUMFORMAT_D7 "Packet writing"
+ IDS_MEDIUMFORMAT_D8 "Data multisession Mode 1 (open recordable disc)"
+ IDS_MEDIUMFORMAT_D9 "Data multisession Mode 2 (open recordable disc)"
+ IDS_MEDIUMFORMAT_A1 "Audio stamped or closed recordable disc (Disk At Once / Session At Once / Track At Once)"
+ IDS_MEDIUMFORMAT_A2 "Audio recordable disc with session not closed (Track At Once or Session At Once)"
+ IDS_MEDIUMFORMAT_A3 "First type of Enhanced CD (aborted)"
+ IDS_MEDIUMFORMAT_A4 "CD Extra"
+ IDS_MEDIUMFORMAT_A5 "Audio disc with session not written (Track At Once)"
+ IDS_MEDIUMFORMAT_M1 "First track data, others audio"
+ IDS_MEDIUMFORMAT_M2 "Mixed-mode made (Track At Once)"
+ IDS_MEDIUMFORMAT_M3 "Kodak Portfolio (as per the Kodak standard)"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_MEDIUMFORMAT_M4 "Video CD"
+ IDS_MEDIUMFORMAT_M5 "CD-i"
+ IDS_MEDIUMFORMAT_M6 "PlayStation (Sony games)"
+ IDS_MEDIUMFORMAT_F1 "Obsolete"
+ IDS_MEDIUMFORMAT_F2 "Obsolete for restricted overwrite DVD (DLA DVD-RW)"
+ IDS_MEDIUMFORMAT_F3 "Completed (non-appendable) DVD (DVD-ROM or closed recordable)"
+ IDS_MEDIUMFORMAT_F4 "Incremental DVD with appendable zone (DLA DVD-R and DVD+RW)"
+ IDS_MEDIUMFORMAT_F5 "Layer Jump DVD-R9 Disc"
+ IDS_MEDIUMFORMAT_F8 "Recordable DVD-R, open"
+ IDS_MEDIUMFORMAT_FA "DVD-RAM cartridge"
+ IDS_MEDIUMFORMAT_GENERICCD "CD (other type)"
+ IDS_BUSSTYPE_ATAPI "ATAPI"
+ IDS_BUSSTYPE_SCSI "SCSI"
+ IDS_BUSSTYPE_1394 "FireWire"
+ IDS_BUSSTYPE_USB "USB"
+ IDS_BUSSTYPE_USB2 "USB 2"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_TRACKTYPE_AUDIO "Audio"
+ IDS_TRACKTYPE_TRACK1 "Mode 1"
+ IDS_TRACKTYPE_TRACK2 "Mode 2"
+ IDS_PRIMOCODE_OK "The operation completed successfully."
+ IDS_PRIMOCODE_CMDSEQUENCE
+ "The function was used in the incorrect sequence. Another PrimoSDK API is required before calling this function."
+ IDS_PRIMOCODE_NOASPI "The ASPI layer is not loading or is in error."
+ IDS_PRIMOCODE_INTERR "An internal error occured."
+ IDS_PRIMOCODE_BADPARAM "The function was passed an invalid parameter."
+ IDS_PRIMOCODE_ALREADYEXIST
+ "The function was passed a pointer to a directory element that already exists in the target data structure."
+ IDS_PRIMOCODE_NOTREADABLE
+ "The function was passed a pointer to source file that either cannot be found or is not readable."
+ IDS_PRIMOCODE_NOSPACE "Completion of the operation would result in too many files for the system memory."
+ IDS_PRIMOCODE_INVALIDMEDIUM "Invalid disc."
+ IDS_PRIMOCODE_RUNNING "The operation whose status is being queried is currently running."
+ IDS_PRIMOCODE_BUR "Buffer underrun occured."
+ IDS_PRIMOCODE_SCSIERROR "Drive communication error."
+ IDS_PRIMOCODE_UNITERROR "The SCSI command sent by the function returned a check condition."
+END
+
+STRINGTABLE
+BEGIN
+ IDS_PRIMOCODE_NOTREADY "Specified drive is not ready."
+ IDS_PRIMOCODE_INVALIDSOURCE
+ "The function was passed a pointer to a disc or file that is not valid."
+ IDS_PRIMOCODE_INCOMPATIBLE
+ "The function was passed a pointer to an image from a type of disc that is not compatible with the capabilities of the recorder."
+ IDS_PRIMOCODE_FILEERROR "The function was passed a pointer to a file that cannot be found."
+ IDS_PRIMOCODE_ITSADEMO "The operation requested by the function would exceed the limits allowed by the Demo version of PrimoSDK."
+ IDS_PRIMOCODE_USERABORT "User abort."
+ IDS_PRIMOCODE_BADHANDLE "The function was passed an invalid PrimoSDK handle."
+ IDS_PRIMOCODE_BADUNIT "Specified drive is not exist."
+ IDS_PRIMOCODE_ERRORLOADING
+ "An error occurred while reading the directory of the specified session/border."
+ IDS_PRIMOCODE_NOAINCONTROL
+ "AIN control cannot be activated, typically because PrimoSDK is running under WinASPI instead of PxHelper."
+ IDS_PRIMOCODE_READERROR "Drive reported a reading error."
+ IDS_PRIMOCODE_WRITEERROR "Drive reported a writing error."
+ IDS_PRIMOCODE_TMPOVERFLOW "A temporary file went into overflow."
+ IDS_PRIMOCODE_DVDSTRUCTERROR
+ "A data structure includes a VIDEO_TS or AUDIO_TS folder that is not compliant with DVD-Video or DVD-Audio rules."
+ IDS_PRIMOCODE_FILETOOLARGE
+ "The function was passed a pointer to a file that is bigger than 9.99 GB for UDF or 4 GB for ISO."
+ IDS_PRIMOCODE_CACHEFULL "Not currently used."
+END
+
+STRINGTABLE
+BEGIN
+ IDS_PRIMOCODE_FEATURE_NOT_SUPPORTED
+ "The device does not support the requested feature."
+ IDS_PRIMOCODE_FEATURE_DISABLED
+ "Use of the requested feature is not included in the license under which the SDK was provided."
+ IDS_PRIMOCODE_CALLBACK_ERROR "Stream terminated by the callback."
+ IDS_PRIMOCODE_PROTECTEDWMA "No permission to burn specified WMA file."
+ IDS_DRIVEERRORCODE_000000 "No Additional Sense Information"
+ IDS_DRIVEERRORCODE_000001 "Filemark Detected"
+ IDS_DRIVEERRORCODE_000002 "End-Of-Partition/Medium Detected"
+ IDS_DRIVEERRORCODE_000003 "Setmark Detected"
+ IDS_DRIVEERRORCODE_000004 "Beginning-Of-Partition/Medium Detected"
+ IDS_DRIVEERRORCODE_000005 "End-Of-Data Detected"
+ IDS_DRIVEERRORCODE_000011 "Audio Play Operation In Progress Audio Play"
+ IDS_DRIVEERRORCODE_000012 "Audio Play Operation Paused Audio Play"
+ IDS_DRIVEERRORCODE_000013
+ "Audio Play Operation Successfully Completed Audio Play"
+ IDS_DRIVEERRORCODE_000014
+ "Audio Play Operation Stopped Due To Error Audio Play"
+ IDS_DRIVEERRORCODE_000015 "No Current Audio Status To Return Audio Play"
+ IDS_DRIVEERRORCODE_000016 "Operation In Progress"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_DRIVEERRORCODE_010B00 "Warning"
+ IDS_DRIVEERRORCODE_010B01 "Warning - Specified Temperature Exceeded"
+ IDS_DRIVEERRORCODE_010B02 "Warning - Enclosure Degraded"
+ IDS_DRIVEERRORCODE_010C0A "Write Error - Padding Blocks Added"
+ IDS_DRIVEERRORCODE_011700
+ "Recovered Data With No Error Correction Applied"
+ IDS_DRIVEERRORCODE_011701 "Recovered Data With Retries"
+ IDS_DRIVEERRORCODE_011702 "Recovered Data With Positive Head Offset"
+ IDS_DRIVEERRORCODE_011703 "Recovered Data With Negative Head Offset"
+ IDS_DRIVEERRORCODE_011704
+ "Recovered Data With Retries And/Or Circ Applied"
+ IDS_DRIVEERRORCODE_011705 "Recovered Data Using Previous Sector Id"
+ IDS_DRIVEERRORCODE_011706
+ "Recovered Data Without ECC - Data Auto-Reallocated"
+ IDS_DRIVEERRORCODE_011707
+ "Recovered Data Without ECC - Recommend Reassignment"
+ IDS_DRIVEERRORCODE_011708 "Recovered Data Without ECC - Recommend Rewrite"
+ IDS_DRIVEERRORCODE_011709 "Recovered Data Without ECC - Data Rewritten"
+ IDS_DRIVEERRORCODE_011800 "Recovered Data With Error Correction Applied"
+ IDS_DRIVEERRORCODE_011801
+ "Recovered Data With Error Correction & Retries Applied"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_DRIVEERRORCODE_011802 "Recovered Data - Data Auto-Reallocated"
+ IDS_DRIVEERRORCODE_011803 "Recovered Data With Circ"
+ IDS_DRIVEERRORCODE_011804 "Recovered Data With L-EC"
+ IDS_DRIVEERRORCODE_011805 "Recovered Data - Recommend Reassignment"
+ IDS_DRIVEERRORCODE_011806 "Recovered Data - Recommend Rewrite"
+ IDS_DRIVEERRORCODE_011807 "Recovered Data With ECC - Data Rewritten"
+ IDS_DRIVEERRORCODE_011808 "Recovered Data With Linking"
+ IDS_DRIVEERRORCODE_011E00 "Recovered Id With ECC Correction"
+ IDS_DRIVEERRORCODE_013700 "Rounded Parameter"
+ IDS_DRIVEERRORCODE_015D00
+ "Failure Prediction Threshold Exceeded - Predicted Logical Unit Failure"
+ IDS_DRIVEERRORCODE_015D01
+ "Failure Prediction Threshold Exceeded - Predicted Media Failure"
+ IDS_DRIVEERRORCODE_015DFF "Failure Prediction Threshold Exceeded (False)"
+ IDS_DRIVEERRORCODE_016A00 "Informational, Refer To Log"
+ IDS_DRIVEERRORCODE_017301 "Power Calibration Area Almost Full"
+ IDS_DRIVEERRORCODE_017306 "PROGRAM MEMORY AREA/PMA IS (Almost) FULL"
+ IDS_DRIVEERRORCODE_020400 "Logical Unit Not Ready, Cause Not Reportable"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_DRIVEERRORCODE_020401 "Logical Unit Is In Process Of Becoming Ready"
+ IDS_DRIVEERRORCODE_020402
+ "Logical Unit Not Ready, Initializing Command. Required"
+ IDS_DRIVEERRORCODE_020403
+ "Logical Unit Not Ready, Manual Intervention Required"
+ IDS_DRIVEERRORCODE_020404 "Logical Unit Not Ready, Format In Progress"
+ IDS_DRIVEERRORCODE_020405 "Logical Unit Not Ready, Rebuild In Progress"
+ IDS_DRIVEERRORCODE_020406
+ "Logical Unit Not Ready, Recalculation In Progress"
+ IDS_DRIVEERRORCODE_020407 "Logical Unit Not Ready, Operation In Progress"
+ IDS_DRIVEERRORCODE_020408 "Logical Unit Not Ready, Long Write In Progress"
+ IDS_DRIVEERRORCODE_020500 "Logical Unit Does Not Respond To Selection"
+ IDS_DRIVEERRORCODE_020600
+ "NO REFERENCE POSITION FOUND (Medium May Be Upside Down)"
+ IDS_DRIVEERRORCODE_023000 "Incompatible Medium Installed"
+ IDS_DRIVEERRORCODE_023001 "Cannot Read Medium - Unknown Format"
+ IDS_DRIVEERRORCODE_023002 "Cannot Read Medium - Incompatible Format"
+ IDS_DRIVEERRORCODE_023003 "Cleaning Cartridge Installed"
+ IDS_DRIVEERRORCODE_023004 "Cannot write medium unknown format"
+ IDS_DRIVEERRORCODE_023005 "Cannot write medium incompatible format"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_DRIVEERRORCODE_023007 "Cleaning Failure"
+ IDS_DRIVEERRORCODE_023502 "Enclosure Services Unavailable"
+ IDS_DRIVEERRORCODE_023A00 "Medium Not Present"
+ IDS_DRIVEERRORCODE_023A01 "Medium Not Present - Tray Closed"
+ IDS_DRIVEERRORCODE_023A02 "Medium Not Present - Tray Open"
+ IDS_DRIVEERRORCODE_023E00 "Logical Unit Has Not Self-Configured Yet"
+ IDS_DRIVEERRORCODE_025300 "Medium Load/Eject Failed"
+ IDS_DRIVEERRORCODE_025302 "Medium Removal Prevented"
+ IDS_DRIVEERRORCODE_025700 "Unable to recover TOC"
+ IDS_DRIVEERRORCODE_026800 "Logical Unit Not Configured"
+ IDS_DRIVEERRORCODE_030014 "Audio play op. Stopped due error (Plextor)"
+ IDS_DRIVEERRORCODE_030200 "No Seek Complete"
+ IDS_DRIVEERRORCODE_030280 "Servo Seek Error (Plextor)"
+ IDS_DRIVEERRORCODE_030281 "Servo Seek Error Sync error (Plextor)"
+ IDS_DRIVEERRORCODE_030282 "Servo Seek Error Header error (Plextor)"
+ IDS_DRIVEERRORCODE_030283 "Servo Seek Error Target not met (Plextor)"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_DRIVEERRORCODE_030300 "Peripheral Device Write Fault"
+ IDS_DRIVEERRORCODE_030301 "No Write Current"
+ IDS_DRIVEERRORCODE_030302 "Excessive Write Errors"
+ IDS_DRIVEERRORCODE_030600 "No reference position found"
+ IDS_DRIVEERRORCODE_030C00 "Write Error"
+ IDS_DRIVEERRORCODE_030C01 "Write Error - Recovered With Auto Reallocation"
+ IDS_DRIVEERRORCODE_030C02 "Write Error - Auto Reallocation Failed"
+ IDS_DRIVEERRORCODE_030C03 "Write Error - Recommend Reassignment"
+ IDS_DRIVEERRORCODE_030C04 "Compression Check Miscompare Error"
+ IDS_DRIVEERRORCODE_030C05 "Data Expansion Occurred During Compression"
+ IDS_DRIVEERRORCODE_030C06 "Block Not Compressible"
+ IDS_DRIVEERRORCODE_030C07 "Write Error - Recovery Needed"
+ IDS_DRIVEERRORCODE_030C08 "Write Error - Recovery Failed"
+ IDS_DRIVEERRORCODE_030C09 "Write Error - Loss Of Streaming"
+ IDS_DRIVEERRORCODE_030C0A "Write Error - Padding blocks added"
+ IDS_DRIVEERRORCODE_031000 "Id CRC Or ECC Error"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_DRIVEERRORCODE_031100 "Unrecovered Read Error"
+ IDS_DRIVEERRORCODE_031101 "Read Retries Exhausted"
+ IDS_DRIVEERRORCODE_031102 "Error Too Long To Correct"
+ IDS_DRIVEERRORCODE_031103 "Multiple Read Errors"
+ IDS_DRIVEERRORCODE_031104
+ "Unrecovered Read Error - Auto Reallocate Failed"
+ IDS_DRIVEERRORCODE_031105 "L-EC Uncorrectable Error"
+ IDS_DRIVEERRORCODE_031106 "Circ Unrecovered Error"
+ IDS_DRIVEERRORCODE_031107 "Re-Synchronization Error"
+ IDS_DRIVEERRORCODE_031108 "Incomplete Block"
+ IDS_DRIVEERRORCODE_031109 "No Gap Found"
+ IDS_DRIVEERRORCODE_03110A "Miscorrected Error"
+ IDS_DRIVEERRORCODE_03110B
+ "Unrecovered Read Error - Recommend Reassignment"
+ IDS_DRIVEERRORCODE_03110C
+ "Unrecovered Read Error - Recommend Rewrite The Data"
+ IDS_DRIVEERRORCODE_03110D "De-Compression CRC Error"
+ IDS_DRIVEERRORCODE_03110E "Cannot Decompress Using Declared Algorithm"
+ IDS_DRIVEERRORCODE_03110F "Error Reading UPC/EAN Number"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_DRIVEERRORCODE_031110 "Error Reading ISRC Number"
+ IDS_DRIVEERRORCODE_031200 "Address Mark Not Found For Id Field"
+ IDS_DRIVEERRORCODE_031300 "Address Mark Not Found For Data Field"
+ IDS_DRIVEERRORCODE_031400 "Recorded Entity Not Found"
+ IDS_DRIVEERRORCODE_031401 "Record Not Found"
+ IDS_DRIVEERRORCODE_031402 "Filemark Or Setmark Not Found"
+ IDS_DRIVEERRORCODE_031403 "End-Of-Data Not Found"
+ IDS_DRIVEERRORCODE_031404 "Block Sequence Error"
+ IDS_DRIVEERRORCODE_031405 "Record Not Found - Recommend Reassignment"
+ IDS_DRIVEERRORCODE_031406 "Record Not Found - Data Auto-Reallocated"
+ IDS_DRIVEERRORCODE_031500 "Random Positioning Error"
+ IDS_DRIVEERRORCODE_031501 "Mechanical Positioning Error"
+ IDS_DRIVEERRORCODE_031502 "Positioning Error Detected By Read Of Medium"
+ IDS_DRIVEERRORCODE_031600 "Data Synchronization Mark Error"
+ IDS_DRIVEERRORCODE_031601 "Data Sync Error - Data Rewritten"
+ IDS_DRIVEERRORCODE_031602 "Data Sync Error - Recommend Rewrite"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_DRIVEERRORCODE_031603 "Data Sync Error - Data Auto-Reallocated"
+ IDS_DRIVEERRORCODE_031604 "Data Sync Error - Recommend Reassignment"
+ IDS_DRIVEERRORCODE_031900 "Defect List Error"
+ IDS_DRIVEERRORCODE_031901 "Defect List Not Available"
+ IDS_DRIVEERRORCODE_031902 "Defect List Error In Primary List"
+ IDS_DRIVEERRORCODE_031903 "Defect List Error In Grown List"
+ IDS_DRIVEERRORCODE_031F00 "Partial Defect List Transfer"
+ IDS_DRIVEERRORCODE_032D00 "Overwrite Error On Update In Place"
+ IDS_DRIVEERRORCODE_033000 "Incompatible medium installed"
+ IDS_DRIVEERRORCODE_033100 "Medium Format Corrupted"
+ IDS_DRIVEERRORCODE_033101 "Format Command Failed Formattable"
+ IDS_DRIVEERRORCODE_033102
+ "Zoned Formatting Failed Due To Spare Linking Formattable"
+ IDS_DRIVEERRORCODE_033200 "No Defect Spare Location Available"
+ IDS_DRIVEERRORCODE_033201 "Defect List Update Failure"
+ IDS_DRIVEERRORCODE_033300 "Tape Length Error"
+ IDS_DRIVEERRORCODE_033600 "Ribbon, Ink, Or Toner Failure"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_DRIVEERRORCODE_033B00 "Sequential Positioning Error"
+ IDS_DRIVEERRORCODE_033B01 "Tape Position Error At Beginning-Of-Medium"
+ IDS_DRIVEERRORCODE_033B02 "Tape Position Error At End-Of-Medium"
+ IDS_DRIVEERRORCODE_033B03
+ "Tape Or Electronic Vertical Forms Unit Not Ready"
+ IDS_DRIVEERRORCODE_033B06 "Failed To Sense Top-Of-Form"
+ IDS_DRIVEERRORCODE_033B07 "Failed To Sense Bottom-Of-Form"
+ IDS_DRIVEERRORCODE_033B08 "Reposition Error"
+ IDS_DRIVEERRORCODE_033B09 "Read Past End Of Medium"
+ IDS_DRIVEERRORCODE_033B0A "Read Past Beginning Of Medium"
+ IDS_DRIVEERRORCODE_033B0B "Position Past End Of Medium"
+ IDS_DRIVEERRORCODE_033B0C "Position Past Beginning Of Medium"
+ IDS_DRIVEERRORCODE_035100 "Erase Failure"
+ IDS_DRIVEERRORCODE_035200 "Cartridge Fault"
+ IDS_DRIVEERRORCODE_035700 "Unable To Recover Table-Of-Contents"
+ IDS_DRIVEERRORCODE_035C02 "Spindles Not Synchronized"
+ IDS_DRIVEERRORCODE_036100 "Video Acquisition Error"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_DRIVEERRORCODE_036101 "Unable To Acquire Video"
+ IDS_DRIVEERRORCODE_036102 "Out Of Focus"
+ IDS_DRIVEERRORCODE_036C00 "Rebuild Failure Occurred"
+ IDS_DRIVEERRORCODE_036D00 "Recalculate Failure Occurred"
+ IDS_DRIVEERRORCODE_0370NN
+ "Decompression Exception Short Algorithm Id Of NN"
+ IDS_DRIVEERRORCODE_037100 "Decompression Exception Long Algorithm Id"
+ IDS_DRIVEERRORCODE_037200 "Session Fixation Error"
+ IDS_DRIVEERRORCODE_037201 "Session Fixation Error Writing Lead-in"
+ IDS_DRIVEERRORCODE_037202 "Session Fixation Error Writing Lead-out"
+ IDS_DRIVEERRORCODE_037300 "CD Control Error"
+ IDS_DRIVEERRORCODE_037302 "Power Calibration Area Is Full"
+ IDS_DRIVEERRORCODE_037303 "Power Calibration Area Error"
+ IDS_DRIVEERRORCODE_037304 "Program Memory Area/RMA Update Failure"
+ IDS_DRIVEERRORCODE_037305 "Program Memory Area/RMA Is Full"
+ IDS_DRIVEERRORCODE_040017 "Cleaning Requested"
+ IDS_DRIVEERRORCODE_040100 "No Index/Sector Signal"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_DRIVEERRORCODE_040500 "Logical unit does not respond to selection"
+ IDS_DRIVEERRORCODE_040800 "Logical Unit Communication Failure"
+ IDS_DRIVEERRORCODE_040801 "Logical Unit Communication Time-Out"
+ IDS_DRIVEERRORCODE_040802 "Logical Unit Communication Parity Error"
+ IDS_DRIVEERRORCODE_040803
+ "Logical Unit Communication CRC Error (Ultra-Dma/32)"
+ IDS_DRIVEERRORCODE_040900 "Track Following Error"
+ IDS_DRIVEERRORCODE_040901 "Tracking Servo Failure"
+ IDS_DRIVEERRORCODE_040902 "Focus Servo Failure"
+ IDS_DRIVEERRORCODE_040903 "Spindle Servo Failure"
+ IDS_DRIVEERRORCODE_040904 "Head Select Fault"
+ IDS_DRIVEERRORCODE_041B00 "Synchronous Data Transfer Error"
+ IDS_DRIVEERRORCODE_041C00 "Defect List Not Found"
+ IDS_DRIVEERRORCODE_041C01 "Primary Defect List Not Found"
+ IDS_DRIVEERRORCODE_041C02 "Grown Defect List Not Found"
+ IDS_DRIVEERRORCODE_043400 "Enclosure Failure"
+ IDS_DRIVEERRORCODE_043500 "Enclosure Services Failure"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_DRIVEERRORCODE_043503 "Enclosure Services Transfer Failure"
+ IDS_DRIVEERRORCODE_043B04 "Slew Failure"
+ IDS_DRIVEERRORCODE_043B05 "Paper Jam"
+ IDS_DRIVEERRORCODE_043B16 "Mechanical Positioning Or Changer Error Load"
+ IDS_DRIVEERRORCODE_043E01 "Logical Unit Failure"
+ IDS_DRIVEERRORCODE_043E02 "Timeout On Logical Unit"
+ IDS_DRIVEERRORCODE_044000 "Ram Failure (Should Use 40 Nn)"
+ IDS_DRIVEERRORCODE_0440NN "Diagnostic Failure On Component Nn (80h-Ffh)"
+ IDS_DRIVEERRORCODE_044100 "Data Path Failure (Should Use 40 Nn)"
+ IDS_DRIVEERRORCODE_044200
+ "Power-On Or Self-Test Failure (Should Use 40 Nn)"
+ IDS_DRIVEERRORCODE_044400 "Internal Target Failure"
+ IDS_DRIVEERRORCODE_044600 "Unsuccessful Soft Reset"
+ IDS_DRIVEERRORCODE_044700 "SCSI Parity Error"
+ IDS_DRIVEERRORCODE_044A00 "Command Phase Error"
+ IDS_DRIVEERRORCODE_044B00 "Data Phase Error"
+ IDS_DRIVEERRORCODE_044C00 "Logical Unit Failed Self-Configuration"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_DRIVEERRORCODE_045300 "Media Load Or Eject Failed Load"
+ IDS_DRIVEERRORCODE_045400 "SCSI To Host System Interface Failure"
+ IDS_DRIVEERRORCODE_046000 "Lamp Failure"
+ IDS_DRIVEERRORCODE_046200 "Scan Head Positioning Error"
+ IDS_DRIVEERRORCODE_046500 "Voltage Fault"
+ IDS_DRIVEERRORCODE_046600 "Automatic Document Feeder Cover Up"
+ IDS_DRIVEERRORCODE_046601 "Automatic Document Feeder Lift Up"
+ IDS_DRIVEERRORCODE_046602 "Document Jam In Automatic Document Feeder"
+ IDS_DRIVEERRORCODE_046603
+ "Document Miss Feed Automatic In Document Feeder"
+ IDS_DRIVEERRORCODE_046700 "Configuration Failure"
+ IDS_DRIVEERRORCODE_046701
+ "Configuration Of Incapable Logical Units Failed"
+ IDS_DRIVEERRORCODE_046702 "Add Logical Unit Failed"
+ IDS_DRIVEERRORCODE_046703 "Modification Of Logical Unit Failed"
+ IDS_DRIVEERRORCODE_046704 "Exchange Of Logical Unit Failed"
+ IDS_DRIVEERRORCODE_046705 "Remove Of Logical Unit Failed"
+ IDS_DRIVEERRORCODE_046706 "Attachment Of Logical Unit Failed"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_DRIVEERRORCODE_046707 "Creation Of Logical Unit Failed"
+ IDS_DRIVEERRORCODE_046901 "Multiple Logical Unit Failures"
+ IDS_DRIVEERRORCODE_046902 "A Parity/ Data Mismatch N/ A"
+ IDS_DRIVEERRORCODE_046E00 "Command To Logical Unit Failed"
+ IDS_DRIVEERRORCODE_04B600 "Media load mechanism failed (Plextor)"
+ IDS_DRIVEERRORCODE_050011 "Audio Play Operation in progress"
+ IDS_DRIVEERRORCODE_050700 "Multiple Peripheral Devices Selected"
+ IDS_DRIVEERRORCODE_051A00 "Parameter List Length Error"
+ IDS_DRIVEERRORCODE_052000 "Invalid Command Operation Code"
+ IDS_DRIVEERRORCODE_052100 "Logical Block Address Out Of Range"
+ IDS_DRIVEERRORCODE_052101 "Invalid Element Address"
+ IDS_DRIVEERRORCODE_052102 "Invalid Address For Write Incremental"
+ IDS_DRIVEERRORCODE_052200 "Illegal Function (Use 20 00, 24 00, Or 26 00)"
+ IDS_DRIVEERRORCODE_052400 "Invalid Field In CDB"
+ IDS_DRIVEERRORCODE_052500 "Logical Unit Not Supported"
+ IDS_DRIVEERRORCODE_052600 "Invalid Field In Parameter List"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_DRIVEERRORCODE_052601 "Parameter Not Supported"
+ IDS_DRIVEERRORCODE_052602 "Parameter Value Invalid"
+ IDS_DRIVEERRORCODE_052603 "Threshold Parameters Not Supported"
+ IDS_DRIVEERRORCODE_052604
+ "Invalid Release Of Active Persistent Reservation"
+ IDS_DRIVEERRORCODE_052700 "Write protected"
+ IDS_DRIVEERRORCODE_052701 "Hardware Write Protected"
+ IDS_DRIVEERRORCODE_052702 "Logical Unit Software Write Protected"
+ IDS_DRIVEERRORCODE_052703 "Associated Write Protect"
+ IDS_DRIVEERRORCODE_052704 "Persistent Write Protect"
+ IDS_DRIVEERRORCODE_052705 "Permanent Write Protect"
+ IDS_DRIVEERRORCODE_052B00
+ "Copy Cannot Execute Since Host Cannot Disconnect"
+ IDS_DRIVEERRORCODE_052C00 "Command Sequence Error"
+ IDS_DRIVEERRORCODE_052C01 "Too Many Windows Specified"
+ IDS_DRIVEERRORCODE_052C02 "Invalid Combination Of Windows Specified"
+ IDS_DRIVEERRORCODE_052C03 "Current Program Area Is Not Empty"
+ IDS_DRIVEERRORCODE_052C04 "Current Program Area Is Empty"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_DRIVEERRORCODE_053000 "Incompatible medium installed"
+ IDS_DRIVEERRORCODE_053002 "Cannot Read Medium - Incompatible Format"
+ IDS_DRIVEERRORCODE_053004 "Cannot Write Medium - Unknown Format"
+ IDS_DRIVEERRORCODE_053005 "Cannot Write Medium - Incompatible Format"
+ IDS_DRIVEERRORCODE_053006 "Cannot Format Medium - Incompatible Medium"
+ IDS_DRIVEERRORCODE_053008 "Cannot Write - Application Code Mismatch"
+ IDS_DRIVEERRORCODE_053009 "Current Session Not Fixated For Append"
+ IDS_DRIVEERRORCODE_053501 "Unsupported Enclosure Function"
+ IDS_DRIVEERRORCODE_053504 "Enclosure Services Transfer Refused"
+ IDS_DRIVEERRORCODE_053800 "Reserved"
+ IDS_DRIVEERRORCODE_053900 "Saving Parameters Not Supported"
+ IDS_DRIVEERRORCODE_053D00 "Invalid Bits In Identify Message"
+ IDS_DRIVEERRORCODE_054300 "Message Error"
+ IDS_DRIVEERRORCODE_055302 "Medium Removal Prevented"
+ IDS_DRIVEERRORCODE_055500 "System Resource Failure"
+ IDS_DRIVEERRORCODE_056300 "End Of User Area Encountered On This Track"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_DRIVEERRORCODE_056301 "Packet Does Not Fit In Available Space"
+ IDS_DRIVEERRORCODE_056400 "Illegal Mode For This Track"
+ IDS_DRIVEERRORCODE_056401 "Invalid Packet Size"
+ IDS_DRIVEERRORCODE_056F00
+ "Copy Protection Key Exchange Failure - Authentication Failure CPP"
+ IDS_DRIVEERRORCODE_056F01
+ "Copy Protection Key Exchange Failure - Key Not Present CPP"
+ IDS_DRIVEERRORCODE_056F02
+ "Copy Protection Key Exchange Failure - Key Not Established CPP"
+ IDS_DRIVEERRORCODE_056F03
+ "Read Of Scrambled Sector Without Authentication CPP"
+ IDS_DRIVEERRORCODE_056F04
+ "Media Region Code Is Mismatched To Logical Unit Region CPP"
+ IDS_DRIVEERRORCODE_056F05
+ "Drive Region Must Be Permanent/Region Reset Count Error CPP"
+ IDS_DRIVEERRORCODE_057203
+ "Session Fixation Error - Incomplete Track In Session"
+ IDS_DRIVEERRORCODE_057204 "Empty Or Partially Written Reserved"
+ IDS_DRIVEERRORCODE_057205 "No More R zone Reservations Are"
+ IDS_DRIVEERRORCODE_058100 "Logical unit is reserved (Plextor)"
+ IDS_DRIVEERRORCODE_058500 "Audio address not valid (Plextor)"
+ IDS_DRIVEERRORCODE_060A00 "Error Log Overflow"
+ IDS_DRIVEERRORCODE_062800
+ "Not Ready To Ready Change, Medium May Have Changed"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_DRIVEERRORCODE_062801 "Import Or Export Element Accessed"
+ IDS_DRIVEERRORCODE_062900 "Power On, Reset, Or Bus Device Reset Occurred"
+ IDS_DRIVEERRORCODE_062901 "Power On Occurred"
+ IDS_DRIVEERRORCODE_062902 "SCSI Bus Reset Occurred"
+ IDS_DRIVEERRORCODE_062903 "Bus Device Reset Function Occurred"
+ IDS_DRIVEERRORCODE_062904 "Device Internal Reset"
+ IDS_DRIVEERRORCODE_062A00 "Parameters Changed"
+ IDS_DRIVEERRORCODE_062A01 "Mode Parameters Changed"
+ IDS_DRIVEERRORCODE_062A02 "Log Parameters Changed"
+ IDS_DRIVEERRORCODE_062A03 "Reservations Preempted"
+ IDS_DRIVEERRORCODE_062E00 "Insufficient Time For Operation Timeout"
+ IDS_DRIVEERRORCODE_062F00 "Commands Cleared By Another Initiator"
+ IDS_DRIVEERRORCODE_063B0D "Medium Destination Element Full"
+ IDS_DRIVEERRORCODE_063B0E "Medium Source Element Empty"
+ IDS_DRIVEERRORCODE_063B0F "End Of Medium Reached"
+ IDS_DRIVEERRORCODE_063B11 "Medium Magazine Not Accessible Load"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_DRIVEERRORCODE_063B12 "Medium Magazine Removed Load"
+ IDS_DRIVEERRORCODE_063B13 "Medium Magazine Inserted Load"
+ IDS_DRIVEERRORCODE_063B14 "Medium Magazine Locked Load"
+ IDS_DRIVEERRORCODE_063B15 "Medium Magazine Unlocked Load"
+ IDS_DRIVEERRORCODE_063F00 "Target Operating Conditions Have Changed"
+ IDS_DRIVEERRORCODE_063F01 "Microcode Has Been Changed"
+ IDS_DRIVEERRORCODE_063F02 "Changed Operating Definition"
+ IDS_DRIVEERRORCODE_063F03 "Inquiry Data Has Changed"
+ IDS_DRIVEERRORCODE_065501 "System Buffer Full"
+ IDS_DRIVEERRORCODE_065A00 "Operator Request Or State Change Input"
+ IDS_DRIVEERRORCODE_065A01 "Operator Medium Removal Request"
+ IDS_DRIVEERRORCODE_065A02 "Operator Selected Write Protect"
+ IDS_DRIVEERRORCODE_065A03 "Operator Selected Write Permit"
+ IDS_DRIVEERRORCODE_065B00 "Log Exception"
+ IDS_DRIVEERRORCODE_065B01 "Threshold Condition Met"
+ IDS_DRIVEERRORCODE_065B02 "Log Counter At Maximum"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_DRIVEERRORCODE_065B03 "Log List Codes Exhausted"
+ IDS_DRIVEERRORCODE_065C00 "Rpl Status Change"
+ IDS_DRIVEERRORCODE_065C01 "Spindles Synchronized"
+ IDS_DRIVEERRORCODE_065E00 "Low Power Condition On"
+ IDS_DRIVEERRORCODE_065E01 "Idle Condition Activated By Timer"
+ IDS_DRIVEERRORCODE_065E02 "Standby Condition Activated By Timer"
+ IDS_DRIVEERRORCODE_065E03 "Idle Condition Activated By Command"
+ IDS_DRIVEERRORCODE_065E04 "Standby Condition Activated By Command"
+ IDS_DRIVEERRORCODE_066A00 "Informational, Refer To Log"
+ IDS_DRIVEERRORCODE_066B00 "State Change Has Occurred"
+ IDS_DRIVEERRORCODE_066B01 "Redundancy Level Got Better"
+ IDS_DRIVEERRORCODE_066B02 "Redundancy Level Got Worse"
+ IDS_DRIVEERRORCODE_072700 "Write Protected"
+ IDS_DRIVEERRORCODE_072701 "Hardware Write Protected"
+ IDS_DRIVEERRORCODE_072702 "Logical Unit Software Write Protected"
+ IDS_DRIVEERRORCODE_072703 "Associated Write Protect"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_DRIVEERRORCODE_072704 "Persistent Write Protect"
+ IDS_DRIVEERRORCODE_072705 "Permanent Write Protect"
+ IDS_DRIVEERRORCODE_082102 "INVALID ADDRESS FOR WRITE (Blank Check)"
+ IDS_DRIVEERRORCODE_098000 "Illegal media (Plextor)"
+ IDS_DRIVEERRORCODE_098001 "Illegal write page parameter (Plextor)"
+ IDS_DRIVEERRORCODE_098005 "Illegal pause length (Plextor)"
+ IDS_DRIVEERRORCODE_098006 "Illegal track num over 99 (Plextor)"
+ IDS_DRIVEERRORCODE_098007 "Illegal incomplete track exist (Plextor)"
+ IDS_DRIVEERRORCODE_09800A "Over transfer data (Plextor)"
+ IDS_DRIVEERRORCODE_09800B "There is no pit (Plextor)"
+ IDS_DRIVEERRORCODE_09800C "Search NWA fail (Plextor)"
+ IDS_DRIVEERRORCODE_0B0006 "I/O Process Terminated, Play Operation Aborted"
+ IDS_DRIVEERRORCODE_0B1111 "Read Error - Loss Of Streaming"
+ IDS_DRIVEERRORCODE_0B4300 "Message error (Plextor)"
+ IDS_DRIVEERRORCODE_0B4500 "Select Or Reselect Failure"
+ IDS_DRIVEERRORCODE_0B4800 "Initiator Detected Error Message Received"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_DRIVEERRORCODE_0B4900 "Invalid Message Error"
+ IDS_DRIVEERRORCODE_0B4DNN "Tagged Overlapped Commands (NN = Queue Tag)"
+ IDS_DRIVEERRORCODE_0B4E00 "Overlapped Commands Attempted"
+ IDS_DRIVEERRORCODE_0BB900 "Audio play operation aborted (Plextor)"
+ IDS_DRIVEERRORCODE_0E1D00 "Miscompare During Verify Operation"
+ IDS_DRIVEERRORCODE_0X0D00 "Reserved"
+ IDS_DRIVEERRORCODE_0X0E00 "Reserved"
+ IDS_DRIVEERRORCODE_0X0F00 "Reserved"
+ IDS_DRIVEERRORCODE_0X2300 "Reserved"
+ IDS_DRIVEERRORCODE_0X4F00 "Reserved"
+ IDS_DRIVEERRORCODE_0X5000 "Write Append Error"
+ IDS_DRIVEERRORCODE_0X5001 "Write Append Position Error"
+ IDS_DRIVEERRORCODE_0X5002 "Position Error Related To Timing"
+ IDS_DRIVEERRORCODE_0X5301 "Unload Tape Failure"
+ IDS_DRIVEERRORCODE_0X5400 "SCSI To Host System Interface Failure"
+ IDS_DRIVEERRORCODE_0X5501 "System Buffer Full"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_DRIVEERRORCODE_0X5600 "Reserved"
+ IDS_DRIVEERRORCODE_0X5800 "Generation Does Not Exist"
+ IDS_DRIVEERRORCODE_0X5900 "Updated Block"
+ IDS_DRIVEERRORCODE_0X5F00 "Reserved"
+ IDS_DRIVEERRORCODE_0X80XX "VENDOR SPECIFIC Through FF XX"
+ IDS_UNITNOTREADY "Drive %c: is not ready."
+ IDS_WAITINGFORDRIVE "Waiting for drive to become ready..."
+ IDS_CONFIRMATION "Confirmation"
+ IDS_MB_CANCELOPERATION "Are you sure you want to cancel this operation?"
+ IDS_UPDATINGDATA "Updating data..."
+ IDS_UNABLEGETDISCINFO "Unable to get disc information."
+ IDS_READINGDISCINFO "Reading disc information..."
+ IDS_DISCERASABLE "Erasable disc."
+ IDS_DISCNONERASABLE "Non Erasable disc."
+ IDS_DISCINFOFORMAT "%s, %s\nFree:\t %s.\nUsed:\t %s.\n%s.\n\n%s."
+ IDS_DISCSIZEFORMAT "%d Min, %d MB (%d sectors)"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_WRONGMEDIUM " Drive %c: contains wrong meda type."
+ IDS_SELECTERASEMETHOD "Plese select erasing method for disc in drive %c:."
+ IDS_QUICKERASE "Quick Erase (Only Table of Contents)"
+ IDS_COMPLETEERASE "Complete Erase"
+ IDS_ERASEREQDISC "Any Rewritable disc (CD-RW, DVD-RW, DVD+RW, ...)."
+ IDS_INITIALIZING "Initializing..."
+ IDS_FINISHING "Finishing..."
+ IDS_COMPLETING "Completing..."
+ IDS_STARTING "Starting..."
+ IDS_CANCELING "Canceling..."
+ IDS_ABORTING "Aborting..."
+ IDS_FINISHED "Finished."
+ IDS_ABORTED "Aborted."
+ IDS_ERROR "Error"
+ IDS_COMPLETED "Completed."
+ IDS_READY "Ready."
+END
+
+STRINGTABLE
+BEGIN
+ IDS_CANCELED "Canceled."
+ IDS_ERASING "Erasing..."
+ IDS_UNKNOWNERROR "Unknown error."
+ IDS_DRIVENOTREADY "Drive not ready."
+ IDS_MEDIUMERASEFAILED "Media erase failed."
+ IDS_UNABLEINITERASE "Unable to initialize erasing."
+ IDS_UNABLEFINERASE "Unable to finalize erasing."
+ IDS_ALREADYERASING "Already erasing."
+ IDS_PRIMOINITFAILED "Unable to initialize burning library."
+ IDS_BURNINGCDDA "Burning Audio CD in drive %c:"
+ IDS_ERROROCCURED "Error occured."
+ IDS_TMPCREATEFAILED "Unable to create temporary file."
+ IDS_BURNINGABORTEDBYUSER "Burning aborted by user."
+ IDS_SHOWLESS "Show Less"
+ IDS_SHOWMORE "Show More"
+ IDS_PREPARING "Preparing"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_BURNING "Burning"
+ IDS_CHECKINGDISC "Checking disc..."
+ IDS_BURNREQDISC "Blank or Open Recordable CD disc (CD-R, CD-RW) with at least %d minutes of free space."
+ IDS_SPEEDBEST "Adjustable Write Speed"
+ IDS_SPEEDMAX "Maximum Speed"
+ IDS_SPEEDMIN "Minimum Speed"
+ IDS_SPEEDMED "Medium Speed"
+ IDS_SPEED "speed"
+ IDS_AT "at"
+ IDS_BURNINGCANCELED "Burning of Audio CD in drive %c: canceled."
+ IDS_REASON "Reason:"
+ IDS_CURRENTOPERATION "Currently:"
+ IDS_LICENSEFAILED "Verification failed."
+ IDS_LICENSEFAILEDMSG "One or more files were not able to be burned due to one of the following reasons:\n- Insufficient License Rights\n- File was not found (or named properly)\nTo burn disc without these files click 'Continue Anyway', otherwise click 'Cancel'"
+ IDS_BURNERROR "Nullsoft Burner Error"
+ IDS_LICENSESUCCESS "Verification completed successfully."
+END
+
+STRINGTABLE
+BEGIN
+ IDS_LICENSEPROGRESS "Verifying files..."
+ IDS_LICENSEITEMPROGRESS "Verifying..."
+ IDS_LICENSEITEMSUCCESS "Ok"
+ IDS_LICENSEITEMFAILED "No license rights to burn."
+ IDS_SKIPPED "Skipped"
+ IDS_SCHEDULED "Scheduled"
+ IDS_PREPARINGDATA "Preparing data..."
+ IDS_PREPARESUCCESS "Finished preparing data."
+ IDS_PREPAREFAILED "Data preparation failed."
+ IDS_PREPAREFAILEDMSG "Some files were not prepared due to an error during preparation.\nTo burn disc without these files click 'Continue Anyway', otherwise click 'Cancel'."
+ IDS_OF "of"
+ IDS_PREPAREITEMSUCCESS "Prepared"
+ IDS_PREPAREITEMFAILED "Unable to decode"
+ IDS_BURNITEMADDFAILED "Unable to add file to CD"
+ IDS_INITIALIZINGBURNER "Initializing burner..."
+ IDS_MASTERINGDISC "Mastering disc..."
+END
+
+STRINGTABLE
+BEGIN
+ IDS_BURNITEMSUCCESS "Finished"
+ IDS_WRITELEADIN "Opening disc / Writing Lead-In..."
+ IDS_WRITELEADOUT "Closing disc / Writing Lead-Out..."
+ IDS_DISCOPEN "Opening disc..."
+ IDS_DISCCLOSE "Closing disc..."
+ IDS_BURNPROGRESS "Burning in progress...( %d%% completed)"
+ IDS_RELEASINGBURNER "Releasing burner..."
+ IDS_BURNFAILED "Error during Audio CD burning process."
+ IDS_BURNSUCCESS "Burning of the Audio CD completed succesfully."
+ IDS_BURNINGCOMPLETED "Burning of the Audio CD in drive %c: completed."
+ IDS_BURNINGSTOPPED "Burning of Audio CD in drive %c: stopped."
+ IDS_FILENOTFOUND "File not found."
+ IDS_DRMNOLICENSE "License needed - protected track."
+ IDS_DRMNOBURNING "License disallows burning."
+ IDS_DRMBURNCOUNTEXCEEDED "No more burns allowed."
+ IDS_NODECODER "Can't find decoder."
+END
+
+STRINGTABLE
+BEGIN
+ IDS_NOFILES "No files."
+ IDS_DECODESERVICEFAILED "Unable to initialize decode service."
+ IDS_LICENSEWRONGFILECOUNT
+ "Verification failed because of wrong file count returned."
+ IDS_BADFILENAME "Bad file name."
+ IDS_CACHEWRITEFAILED "Error writing cache file."
+ IDS_DECODESTARTFAILED "Unable to initialize preparation process."
+ IDS_BURNSTARTFAILED "Unable to initialize burn process."
+ IDS_MASTERINGFAILED "Audio CD mastering failed."
+ IDS_BEGINBURNFAILED "Burner initialization failed."
+ IDS_ENDBURNFAILED "Burner releasing failed."
+ IDS_WRITEAUDIOFAILED "Writing to the Audio CD failed."
+ IDS_LIBERRORPREFIX "\n\nLibrary error: "
+ IDS_DRVERRORPREFIX "\nDrive error: "
+ IDS_CHKDSCWRONGPARAMETER
+ "Unable to check disc - at least one parameter is wrong."
+ IDS_CHKDSCMSGPUMPFAILED "Unable to check disc - failed to process messages."
+ IDS_CHKDSCDIALOGFAILED "Unable to check disc - internal initialization failed."
+END
+
+STRINGTABLE
+BEGIN
+ IDS_MB_CANCELBURNING "Are you sure you want to cancel burning?"
+ IDS_TEMPORARY_FILE "Temporary File"
+END
+
+STRINGTABLE
+BEGIN
+ 65535 "{C14FAE1D-B410-459f-B008-1A8BE3633000}"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/Src/burnlib/burnlib.sln b/Src/burnlib/burnlib.sln
new file mode 100644
index 00000000..8e99e0d3
--- /dev/null
+++ b/Src/burnlib/burnlib.sln
@@ -0,0 +1,67 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "burnlib", "burnlib.vcproj", "{374717BA-EF3A-4BF6-AC4D-A532E08BE904}"
+ ProjectSection(ProjectDependencies) = postProject
+ {8FBD5E01-B920-44D8-9687-88AE0C3CA833} = {8FBD5E01-B920-44D8-9687-88AE0C3CA833}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "burnlibres", "resdll\resdll.vcproj", "{8FBD5E01-B920-44D8-9687-88AE0C3CA833}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winampv6", "..\Winamp\winampv6.vcproj", "{7DE5C6C7-DAF2-42F9-9324-C8CF4E7E8AC5}"
+ ProjectSection(ProjectDependencies) = postProject
+ {8FBD5E01-B920-44D8-9687-88AE0C3CA833} = {8FBD5E01-B920-44D8-9687-88AE0C3CA833}
+ {374717BA-EF3A-4BF6-AC4D-A532E08BE904} = {374717BA-EF3A-4BF6-AC4D-A532E08BE904}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "in_wmvdrm", "..\in_wmvdrm\in_wmvdrm.vcproj", "{9362E6C2-EFCC-4104-8671-78222E0A5FCC}"
+ ProjectSection(ProjectDependencies) = postProject
+ {8FBD5E01-B920-44D8-9687-88AE0C3CA833} = {8FBD5E01-B920-44D8-9687-88AE0C3CA833}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Profiling = Profiling
+ Release = Release
+ Revoked = Revoked
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {374717BA-EF3A-4BF6-AC4D-A532E08BE904}.Debug.ActiveCfg = Debug|Win32
+ {374717BA-EF3A-4BF6-AC4D-A532E08BE904}.Debug.Build.0 = Debug|Win32
+ {374717BA-EF3A-4BF6-AC4D-A532E08BE904}.Profiling.ActiveCfg = Release|Win32
+ {374717BA-EF3A-4BF6-AC4D-A532E08BE904}.Profiling.Build.0 = Release|Win32
+ {374717BA-EF3A-4BF6-AC4D-A532E08BE904}.Release.ActiveCfg = Release|Win32
+ {374717BA-EF3A-4BF6-AC4D-A532E08BE904}.Release.Build.0 = Release|Win32
+ {374717BA-EF3A-4BF6-AC4D-A532E08BE904}.Revoked.ActiveCfg = Release|Win32
+ {374717BA-EF3A-4BF6-AC4D-A532E08BE904}.Revoked.Build.0 = Release|Win32
+ {8FBD5E01-B920-44D8-9687-88AE0C3CA833}.Debug.ActiveCfg = Debug|Win32
+ {8FBD5E01-B920-44D8-9687-88AE0C3CA833}.Debug.Build.0 = Debug|Win32
+ {8FBD5E01-B920-44D8-9687-88AE0C3CA833}.Profiling.ActiveCfg = Release|Win32
+ {8FBD5E01-B920-44D8-9687-88AE0C3CA833}.Profiling.Build.0 = Release|Win32
+ {8FBD5E01-B920-44D8-9687-88AE0C3CA833}.Release.ActiveCfg = Release|Win32
+ {8FBD5E01-B920-44D8-9687-88AE0C3CA833}.Release.Build.0 = Release|Win32
+ {8FBD5E01-B920-44D8-9687-88AE0C3CA833}.Revoked.ActiveCfg = Release|Win32
+ {8FBD5E01-B920-44D8-9687-88AE0C3CA833}.Revoked.Build.0 = Release|Win32
+ {7DE5C6C7-DAF2-42F9-9324-C8CF4E7E8AC5}.Debug.ActiveCfg = Debug|Win32
+ {7DE5C6C7-DAF2-42F9-9324-C8CF4E7E8AC5}.Debug.Build.0 = Debug|Win32
+ {7DE5C6C7-DAF2-42F9-9324-C8CF4E7E8AC5}.Profiling.ActiveCfg = Profiling|Win32
+ {7DE5C6C7-DAF2-42F9-9324-C8CF4E7E8AC5}.Profiling.Build.0 = Profiling|Win32
+ {7DE5C6C7-DAF2-42F9-9324-C8CF4E7E8AC5}.Release.ActiveCfg = Release|Win32
+ {7DE5C6C7-DAF2-42F9-9324-C8CF4E7E8AC5}.Release.Build.0 = Release|Win32
+ {7DE5C6C7-DAF2-42F9-9324-C8CF4E7E8AC5}.Revoked.ActiveCfg = Release|Win32
+ {7DE5C6C7-DAF2-42F9-9324-C8CF4E7E8AC5}.Revoked.Build.0 = Release|Win32
+ {9362E6C2-EFCC-4104-8671-78222E0A5FCC}.Debug.ActiveCfg = Debug|Win32
+ {9362E6C2-EFCC-4104-8671-78222E0A5FCC}.Debug.Build.0 = Debug|Win32
+ {9362E6C2-EFCC-4104-8671-78222E0A5FCC}.Profiling.ActiveCfg = Profiling|Win32
+ {9362E6C2-EFCC-4104-8671-78222E0A5FCC}.Profiling.Build.0 = Profiling|Win32
+ {9362E6C2-EFCC-4104-8671-78222E0A5FCC}.Release.ActiveCfg = Release|Win32
+ {9362E6C2-EFCC-4104-8671-78222E0A5FCC}.Release.Build.0 = Release|Win32
+ {9362E6C2-EFCC-4104-8671-78222E0A5FCC}.Revoked.ActiveCfg = Revoked|Win32
+ {9362E6C2-EFCC-4104-8671-78222E0A5FCC}.Revoked.Build.0 = Revoked|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/Src/burnlib/burnlib.vcproj b/Src/burnlib/burnlib.vcproj
new file mode 100644
index 00000000..f1d15412
--- /dev/null
+++ b/Src/burnlib/burnlib.vcproj
@@ -0,0 +1,284 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="burnlib"
+ ProjectGUID="{374717BA-EF3A-4BF6-AC4D-A532E08BE904}"
+ RootNamespace="burnlib"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../Wasabi"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB;"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ TreatWChar_tAsBuiltInType="true"
+ ForceConformanceInForLoopScope="true"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="./lib/burnlibd.lib"
+ IgnoreAllDefaultLibraries="true"
+ IgnoreDefaultLibraryNames=""
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ FavorSizeOrSpeed="2"
+ AdditionalIncludeDirectories="../Wasabi;"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ StringPooling="true"
+ ExceptionHandling="0"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="burnlib.h"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="./lib/burnlib.lib"
+ IgnoreAllDefaultLibraries="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\common.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\eraseMedium.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\item.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\main.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\playlist.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\uiBurnPlayList.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\uiCheckMedium.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\uiEraseMedium.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\uiUnitReady.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\uiUpdatingData.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\unitStatusText.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\api.h"
+ >
+ </File>
+ <File
+ RelativePath=".\burnlib.h"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\eraseMedium.h"
+ >
+ </File>
+ <File
+ RelativePath=".\item.h"
+ >
+ </File>
+ <File
+ RelativePath=".\main.h"
+ >
+ </File>
+ <File
+ RelativePath=".\manager.h"
+ >
+ </File>
+ <File
+ RelativePath=".\playlist.h"
+ >
+ </File>
+ <File
+ RelativePath=".\primosdk.h"
+ >
+ </File>
+ <File
+ RelativePath=".\resource.h"
+ >
+ </File>
+ <File
+ RelativePath=".\uiBurnPlaylist.h"
+ >
+ </File>
+ <File
+ RelativePath=".\uiCheckMedium.h"
+ >
+ </File>
+ <File
+ RelativePath=".\uiEraseMedium.h"
+ >
+ </File>
+ <File
+ RelativePath=".\uiUnitReady.h"
+ >
+ </File>
+ <File
+ RelativePath=".\uiUpdatingData.h"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/Src/burnlib/common.cpp b/Src/burnlib/common.cpp
new file mode 100644
index 00000000..796531f4
--- /dev/null
+++ b/Src/burnlib/common.cpp
@@ -0,0 +1,261 @@
+#include "./main.h"
+#include "./resource.h"
+#include "./primosdk.h"
+#include <strsafe.h>
+
+
+DWORD BeginBurn(obj_primo *primoSDK, DWORD drive, WABURNSTRUCT *burnstruct)
+{
+ burnstruct->primoSDK = primoSDK;
+ burnstruct->drive = drive;
+ DWORD rc[3] = { PRIMOSDK_ERROR, PRIMOSDK_ERROR, PRIMOSDK_ERROR};
+ burnstruct->blocker = (PBYTE)("WINAMPBURNER v1.0");
+ DWORD retCode = PRIMOSDK_OK;
+ // init Sonic PrimoSDK
+ if (!primoSDK)
+ return PRIMOSDK_NOTLOADED;
+
+ // block drive
+ rc[0] = primoSDK->UnitVxBlock(&burnstruct->drive, PRIMOSDK_LOCK, burnstruct->blocker);
+ if (PRIMOSDK_OK != rc[0]) retCode = rc[0];
+ else
+ {
+ rc[1] = primoSDK->UnitAIN(&burnstruct->drive, PRIMOSDK_LOCK);
+ if (PRIMOSDK_OK != rc[1]) retCode = rc[1];
+ else
+ {
+ rc[2] = primoSDK->UnitLock(&burnstruct->drive, PRIMOSDK_LOCK);
+ if (PRIMOSDK_OK != rc[2]) retCode = rc[2];
+ }
+ }
+ if (PRIMOSDK_OK != retCode)
+ {
+ if (PRIMOSDK_OK == rc[2]) primoSDK->UnitLock(&burnstruct->drive, PRIMOSDK_UNLOCK);
+ if (PRIMOSDK_OK == rc[1]) primoSDK->UnitAIN(&burnstruct->drive, PRIMOSDK_UNLOCK);
+ if (PRIMOSDK_OK == rc[0]) primoSDK->UnitVxBlock(&burnstruct->drive, PRIMOSDK_UNLOCK, burnstruct->blocker);
+ burnstruct->drive = 0x0000;
+ burnstruct->blocker = NULL;
+ burnstruct->primoSDK = NULL;
+ }
+ return retCode;
+}
+
+DWORD EndBurn(WABURNSTRUCT *burnstruct)
+{
+ if (!burnstruct) return PRIMOSDK_ERROR;
+ if (0x0000 == burnstruct->drive) return PRIMOSDK_OK;
+ DWORD rc[4];
+ rc[0] = burnstruct->primoSDK->UnitLock(&burnstruct->drive, PRIMOSDK_UNLOCK);
+
+ rc[1] = burnstruct->primoSDK->MoveMedium(&burnstruct->drive,
+ PRIMOSDK_IMMEDIATE | ((burnstruct->eject) ? PRIMOSDK_OPENTRAYEJECT : 0));
+ if (0 == burnstruct->eject)
+ rc[1] = PRIMOSDK_OK;
+
+ rc[2] = burnstruct->primoSDK->UnitAIN(&burnstruct->drive, PRIMOSDK_UNLOCK);
+ rc[3] = burnstruct->primoSDK->UnitVxBlock(&burnstruct->drive, PRIMOSDK_UNLOCK, burnstruct->blocker);
+
+ burnstruct->drive = 0x0000;
+ burnstruct->blocker = NULL;
+
+ int len = sizeof(rc)/sizeof(DWORD);
+ for (int i = 0; i < len; i++) { if (PRIMOSDK_OK != rc[i]) return rc[i]; }
+
+ return PRIMOSDK_OK;
+}
+
+DWORD GetMediumInfo(obj_primo *primoSDK, DWORD *drive, WAMEDIUMINFO *info)
+{
+ DWORD retCode(PRIMOSDK_OK), erasable(0);
+
+ if (MAXDWORD != info->mediumType || MAXDWORD != info->mediumFormat || MAXDWORD != info->erasable ||
+ MAXDWORD != info->tracks || MAXDWORD != info->usedSectors || MAXDWORD != info->freeSectors || MAXDWORD != info->recordable)
+ {
+ retCode = primoSDK->DiscInfoEx(drive, 0,(MAXDWORD == info->mediumType && MAXDWORD == info->recordable) ? NULL : &info->mediumType,
+ (MAXDWORD == info->mediumFormat) ? NULL : &info->mediumFormat,
+ &erasable,
+ (MAXDWORD == info->tracks) ? NULL : &info->tracks,
+ (MAXDWORD == info->usedSectors) ? NULL : &info->usedSectors,
+ (MAXDWORD == info->freeSectors) ? NULL : &info->freeSectors);
+ if (MAXDWORD != info->erasable) info->erasable = (TRUE == erasable);
+ if (MAXDWORD != info->recordable) info->recordable = (PRIMOSDK_COMPLIANTGOLD == info->mediumType || PRIMOSDK_BLANK == info->mediumType);
+ if (PRIMOSDK_OK != retCode) return retCode;
+ }
+
+ DWORD medium, rfu3;
+ BOOL needMediumInfo = (MAXDWORD != info->medium || MAXDWORD != info->isCD || MAXDWORD != info->isDCD || MAXDWORD != info->isDVD || MAXDWORD != info->isDLDVD);
+ if (MAXDWORD != info->protectedDVD || needMediumInfo)
+ {
+ retCode = primoSDK->DiscInfo2(drive, !needMediumInfo ? NULL : &medium,
+ (MAXDWORD == info->protectedDVD) ? NULL : &info->protectedDVD,
+ NULL,
+ !needMediumInfo ? NULL : &info->medium,
+ &rfu3);
+ }
+
+ if (MAXDWORD != info->isCD) info->isCD = (PRIMOSDK_CDROM == info->medium || PRIMOSDK_CDR == info->medium || PRIMOSDK_CDRW == info->medium);
+ if (MAXDWORD != info->isDCD) info->isDCD = (PRIMOSDK_DDCDR == info->medium || PRIMOSDK_DDCDRW == info->medium);
+ if (MAXDWORD != info->isDVD) info->isDVD = (PRIMOSDK_DDCDROM == info->medium || PRIMOSDK_DVDR == info->medium || PRIMOSDK_DVDROM == info->medium || PRIMOSDK_DVDRAM == info->medium ||
+ PRIMOSDK_DVDRW == info->medium || PRIMOSDK_DVDPRW == info->medium || PRIMOSDK_DVDPR == info->medium);
+ if (MAXDWORD != info->isDLDVD) info->isDLDVD = (PRIMOSDK_DVDPR9 == info->medium);
+ return retCode;
+
+}
+
+
+wchar_t* GetMediumText(wchar_t *buffer, unsigned int cchBuffer,DWORD medium)
+{
+ UINT uid = IDS_UNKNOWN;
+ switch(medium)
+ {
+ case PRIMOSDK_CDROM: uid = IDS_MEDIUM_CD; break;
+ case PRIMOSDK_CDR: uid = IDS_MEDIUM_CDR; break;
+ case PRIMOSDK_CDRW: uid = IDS_MEDIUM_CDRW; break;
+ case PRIMOSDK_DVDR: uid = IDS_MEDIUM_DVDR; break;
+ case PRIMOSDK_DVDROM: uid = IDS_MEDIUM_DVD; break;
+ case PRIMOSDK_DVDRAM: uid = IDS_MEDIUM_DVDRAM; break;
+ case PRIMOSDK_DVDRW: uid = IDS_MEDIUM_DVDRW; break;
+ case PRIMOSDK_DVDPRW: uid = IDS_MEDIUM_DVDPRW; break;
+ case PRIMOSDK_DVDPR: uid = IDS_MEDIUM_DVDPR; break;
+ case PRIMOSDK_DDCDROM: uid = IDS_MEDIUM_DDCD; break;
+ case PRIMOSDK_DDCDR: uid = IDS_MEDIUM_DDCDR; break;
+ case PRIMOSDK_DDCDRW: uid = IDS_MEDIUM_DDCDRW; break;
+ case PRIMOSDK_DVDPR9: uid = IDS_MEDIUM_DVDPR9; break;
+ case PRIMOSDK_DVDR9: uid = IDS_MEDIUM_DVDR9; break;
+ case PRIMOSDK_BDR: uid = IDS_MEDIUM_BDR; break;
+ case PRIMOSDK_BDRE: uid = IDS_MEDIUM_BDRE; break;
+ }
+ LoadStringW(hResource, uid, buffer, cchBuffer);
+ return buffer;
+}
+wchar_t*GetMediumTypeText(wchar_t *buffer, unsigned int cchBuffer, DWORD type)
+{
+ UINT uid = IDS_UNKNOWN;
+ switch(type)
+ {
+ case PRIMOSDK_SILVER: uid = IDS_MEDIUMTYPE_SILVER; break;
+ case PRIMOSDK_COMPLIANTGOLD: uid = IDS_MEDIUMTYPE_COMPILATIONGOLD; break;
+ case PRIMOSDK_OTHERGOLD: uid = IDS_MEDIUMTYPE_OTHERGOLD; break;
+ case PRIMOSDK_BLANK: uid = IDS_MEDIUMTYPE_BLANK; break;
+ }
+ LoadStringW(hResource, uid, buffer, cchBuffer);
+ return buffer;
+}
+wchar_t* GetMediumFormatText(wchar_t *buffer, unsigned int cchBuffer, DWORD format)
+{
+ UINT uid = IDS_UNKNOWN;
+ switch(format)
+ {
+ case PRIMOSDK_B1: uid = IDS_MEDIUMFORMAT_B1; break;
+ case PRIMOSDK_D1: uid = IDS_MEDIUMFORMAT_D1; break;
+ case PRIMOSDK_D2: uid = IDS_MEDIUMFORMAT_D2; break;
+ case PRIMOSDK_D3: uid = IDS_MEDIUMFORMAT_D3; break;
+ case PRIMOSDK_D4: uid = IDS_MEDIUMFORMAT_D4; break;
+ case PRIMOSDK_D5: uid = IDS_MEDIUMFORMAT_D5; break;
+ case PRIMOSDK_D6: uid = IDS_MEDIUMFORMAT_D6; break;
+ case PRIMOSDK_D7: uid = IDS_MEDIUMFORMAT_D7; break;
+ case PRIMOSDK_D8: uid = IDS_MEDIUMFORMAT_D8; break;
+ case PRIMOSDK_D9: uid = IDS_MEDIUMFORMAT_D9; break;
+ case PRIMOSDK_A1: uid = IDS_MEDIUMFORMAT_A1; break;
+ case PRIMOSDK_A2: uid = IDS_MEDIUMFORMAT_A2; break;
+ case PRIMOSDK_A3: uid = IDS_MEDIUMFORMAT_A3; break;
+ case PRIMOSDK_A4: uid = IDS_MEDIUMFORMAT_A4; break;
+ case PRIMOSDK_A5: uid = IDS_MEDIUMFORMAT_A5; break;
+ case PRIMOSDK_M1: uid = IDS_MEDIUMFORMAT_M1; break;
+ case PRIMOSDK_M2: uid = IDS_MEDIUMFORMAT_M2; break;
+ case PRIMOSDK_M3: uid = IDS_MEDIUMFORMAT_M3; break;
+ case PRIMOSDK_M4: uid = IDS_MEDIUMFORMAT_M4; break;
+ case PRIMOSDK_M5: uid = IDS_MEDIUMFORMAT_M5; break;
+ case PRIMOSDK_M6: uid = IDS_MEDIUMFORMAT_M6; break;
+ case PRIMOSDK_F1: uid = IDS_MEDIUMFORMAT_F1; break;
+ case PRIMOSDK_F2: uid = IDS_MEDIUMFORMAT_F2; break;
+ case PRIMOSDK_F3: uid = IDS_MEDIUMFORMAT_F3; break;
+ case PRIMOSDK_F4: uid = IDS_MEDIUMFORMAT_F4; break;
+ case PRIMOSDK_F5: uid = IDS_MEDIUMFORMAT_F5; break;
+ case PRIMOSDK_F8: uid = IDS_MEDIUMFORMAT_F8; break;
+ case PRIMOSDK_FA: uid = IDS_MEDIUMFORMAT_FA; break;
+ case PRIMOSDK_GENERICCD: uid = IDS_MEDIUMFORMAT_GENERICCD; break;
+ }
+ LoadStringW(hResource, uid, buffer, cchBuffer);
+ return buffer;
+}
+wchar_t* GetPrimoCodeText(wchar_t *buffer, unsigned int cchBuffer, DWORD primoCode)
+{
+ UINT uid = IDS_UNKNOWN;
+ switch(primoCode)
+ {
+ case PRIMOSDK_OK: uid = IDS_PRIMOCODE_OK; break;
+ case PRIMOSDK_CMDSEQUENCE: uid = IDS_PRIMOCODE_CMDSEQUENCE; break;
+ case PRIMOSDK_NOASPI: uid = IDS_PRIMOCODE_NOASPI; break; //PRIMOSDK_NO_DRIVER - is the same code
+ case PRIMOSDK_INTERR: uid = IDS_PRIMOCODE_INTERR; break;
+ case PRIMOSDK_BADPARAM: uid = IDS_PRIMOCODE_BADPARAM; break;
+ case PRIMOSDK_ALREADYEXIST: uid = IDS_PRIMOCODE_ALREADYEXIST; break;
+ case PRIMOSDK_NOTREADABLE: uid = IDS_PRIMOCODE_NOTREADABLE; break;
+ case PRIMOSDK_NOSPACE: uid = IDS_PRIMOCODE_NOSPACE; break;
+ case PRIMOSDK_INVALIDMEDIUM: uid = IDS_PRIMOCODE_INVALIDMEDIUM; break;
+ case PRIMOSDK_RUNNING: uid = IDS_PRIMOCODE_RUNNING; break;
+ case PRIMOSDK_BUR: uid = IDS_PRIMOCODE_BUR; break;
+ case PRIMOSDK_SCSIERROR: uid = IDS_PRIMOCODE_SCSIERROR; break;
+ case PRIMOSDK_UNITERROR: uid = IDS_PRIMOCODE_UNITERROR; break;
+ case PRIMOSDK_NOTREADY: uid = IDS_PRIMOCODE_NOTREADY; break;
+ case PRIMOSDK_INVALIDSOURCE: uid = IDS_PRIMOCODE_INVALIDSOURCE; break;
+ case PRIMOSDK_INCOMPATIBLE: uid = IDS_PRIMOCODE_INCOMPATIBLE; break;
+ case PRIMOSDK_FILEERROR: uid = IDS_PRIMOCODE_FILEERROR; break;
+ case PRIMOSDK_ITSADEMO: uid = IDS_PRIMOCODE_ITSADEMO; break;
+ case PRIMOSDK_USERABORT: uid = IDS_PRIMOCODE_USERABORT; break;
+ case PRIMOSDK_BADHANDLE: uid = IDS_PRIMOCODE_BADHANDLE; break;
+ case PRIMOSDK_BADUNIT: uid = IDS_PRIMOCODE_BADUNIT; break;
+ case PRIMOSDK_ERRORLOADING: uid = IDS_PRIMOCODE_ERRORLOADING; break;
+ case PRIMOSDK_NOAINCONTROL: uid = IDS_PRIMOCODE_NOAINCONTROL; break;
+ case PRIMOSDK_READERROR: uid = IDS_PRIMOCODE_READERROR; break;
+ case PRIMOSDK_WRITEERROR: uid = IDS_PRIMOCODE_WRITEERROR; break;
+ case PRIMOSDK_TMPOVERFLOW: uid = IDS_PRIMOCODE_TMPOVERFLOW; break;
+ case PRIMOSDK_DVDSTRUCTERROR: uid = IDS_PRIMOCODE_DVDSTRUCTERROR; break;
+ case PRIMOSDK_FILETOOLARGE: uid = IDS_PRIMOCODE_FILETOOLARGE; break;
+ case PRIMOSDK_CACHEFULL: uid = IDS_PRIMOCODE_CACHEFULL; break;
+ case PRIMOSDK_FEATURE_NOT_SUPPORTED: uid = IDS_PRIMOCODE_FEATURE_NOT_SUPPORTED; break;
+ case PRIMOSDK_FEATURE_DISABLED: uid = IDS_PRIMOCODE_FEATURE_DISABLED; break;
+ case PRIMOSDK_CALLBACK_ERROR: uid = IDS_PRIMOCODE_CALLBACK_ERROR; break;
+ case PRIMOSDK_PROTECTEDWMA: uid = IDS_PRIMOCODE_PROTECTEDWMA; break;
+ }
+ LoadStringW(hResource, uid, buffer, cchBuffer);
+ return buffer;
+
+}
+wchar_t* GetBussText(wchar_t *buffer, unsigned int cchBuffer, DWORD bussType)
+{
+ UINT uid = IDS_UNKNOWN;
+ switch(bussType)
+ {
+ case PRIMOSDK_ATAPI: uid = IDS_BUSSTYPE_ATAPI; break;
+ case PRIMOSDK_SCSI: uid = IDS_BUSSTYPE_SCSI; break;
+ case PRIMOSDK_1394: uid = IDS_BUSSTYPE_1394; break;
+ case PRIMOSDK_USB: uid = IDS_BUSSTYPE_USB; break;
+ case PRIMOSDK_USB2: uid = IDS_BUSSTYPE_USB2; break;
+ }
+ LoadStringW(hResource, uid, buffer, cchBuffer);
+ return buffer;
+}
+
+wchar_t* GetTrackTypeText(wchar_t *buffer, unsigned int cchBuffer, DWORD trackType)
+{
+ UINT uid = IDS_UNKNOWN;
+ switch(trackType)
+ {
+ case PRIMOSDK_AUDIO_TRACK: uid = IDS_TRACKTYPE_AUDIO; break;
+ case PRIMOSDK_MODE1_TRACK: uid = IDS_TRACKTYPE_TRACK2; break;
+ case PRIMOSDK_MODE2_TRACK: uid = IDS_TRACKTYPE_TRACK2; break;
+ }
+ LoadStringW(hResource, uid, buffer, cchBuffer);
+ return buffer;
+}
+
+wchar_t* GetTimeString(wchar_t *string, unsigned int cchLen, unsigned int timesec)
+{
+ unsigned int min = timesec / 60;
+ if (min > 0) timesec = timesec % 60;
+ unsigned int hour = min / 60;
+ if (hour > 0) min = min % 60;
+ StringCchPrintfW(string, cchLen, L"%02d:%02d:%02d", hour, min, timesec);
+ return string;
+} \ No newline at end of file
diff --git a/Src/burnlib/eraseMedium.cpp b/Src/burnlib/eraseMedium.cpp
new file mode 100644
index 00000000..1ce2f5f4
--- /dev/null
+++ b/Src/burnlib/eraseMedium.cpp
@@ -0,0 +1,183 @@
+#include "./eraseMedium.h"
+#include "api.h"
+#include <api/service/waservicefactory.h>
+
+EraseMedium::EraseMedium(void)
+{
+ primoSDK=0;
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(obj_primo::getServiceGuid());
+ if (sf) primoSDK = reinterpret_cast<obj_primo *>(sf->getInterface());
+
+ hThread = NULL;
+ evntStop = NULL;
+ evntThreadExit = NULL;
+ errorCode = PRIMOSDK_OK;
+ notifyCB = NULL;
+}
+
+EraseMedium::~EraseMedium(void)
+{
+ Stop();
+
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(obj_primo::getServiceGuid());
+ if (sf) sf->releaseInterface(primoSDK);
+}
+
+DWORD EraseMedium::SetEject(DWORD eject)
+{
+ DWORD tmp = this->eject;
+ this->eject = eject;
+ return tmp;
+}
+
+DWORD EraseMedium::Start(DWORD drive, DWORD eraseMode, ERASEMEDIUMCALLBACK notifyCB, void *userParam, int block)
+{
+ this->notifyCB = notifyCB;
+ this->userparam = userParam;
+ OnNotify(ERASEMEDIUM_READY, PRIMOSDK_OK);
+ if (hThread)
+ {
+ OnNotify(ERASEMEDIUM_ALREADYSTARTED, PRIMOSDK_OK);
+ return PRIMOSDK_OK;
+ }
+
+ OnNotify(ERASEMEDIUM_INITIALIZING, PRIMOSDK_OK);
+
+ if (!primoSDK)
+ {
+ OnNotify(ERASEMEDIUM_UNABLEINITPRIMO, PRIMOSDK_NOTLOADED);
+ return errorCode;
+ }
+
+ // check unit
+ errorCode = primoSDK->UnitReady(&drive);
+ if (PRIMOSDK_OK != errorCode)
+ {
+ OnNotify(ERASEMEDIUM_DEVICENOTREADY, errorCode);
+ return errorCode;
+ }
+
+ // check that disc is erasable
+ DWORD erasable;
+ errorCode = primoSDK->DiscInfoEx(&drive, 0, NULL, NULL, &erasable, NULL, NULL, NULL);
+ if (PRIMOSDK_OK != errorCode)
+ {
+ OnNotify(ERASEMEDIUM_DISCINFOERROR, errorCode);
+ return errorCode;
+ }
+ if (!erasable)
+ {
+ OnNotify(ERASEMEDIUM_DISCNOTERASABLE, PRIMOSDK_OK);
+ return errorCode;
+ }
+
+ // begin burn
+ errorCode = BeginBurn(primoSDK, drive, &bs);
+ if (PRIMOSDK_OK != errorCode)
+ {
+ OnNotify(ERASEMEDIUM_BEGINBURNFAILED, errorCode);
+ return errorCode;
+ }
+
+ // erasing
+ errorCode = primoSDK->EraseMedium(&bs.drive, eraseMode);
+ if(PRIMOSDK_OK == errorCode)
+ {
+ OnNotify(ERASEMEDIUM_ERASING, PRIMOSDK_OK);
+ evntStop = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (block) errorCode = StatusThread(this);
+ else
+ {
+ DWORD threadID;
+ hThread = CreateThread(NULL, 0, StatusThread, (LPVOID)this, NULL, &threadID);
+ }
+ }
+ else
+ {
+ OnNotify(ERASEMEDIUM_ERASEMEDIUMFAILED, errorCode);
+ }
+ return errorCode;
+
+}
+void EraseMedium::Stop(void)
+{
+
+ if (hThread && evntStop)
+ {
+ DWORD waitResult;
+ MSG msg;
+ if (!evntThreadExit) evntThreadExit = CreateEvent(NULL, FALSE, FALSE, NULL);
+ SetEvent(evntStop);
+
+ while(WAIT_TIMEOUT == (waitResult = WaitForSingleObject(evntThreadExit, 10)))
+ {
+ if (!evntStop) break;
+ while(PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ TranslateMessage(&msg);
+ DispatchMessageW(&msg);
+ }
+ }
+ CloseHandle(evntThreadExit);
+ evntThreadExit = NULL;
+ }
+}
+
+
+DWORD EraseMedium::OnNotify(DWORD eraseCode, DWORD primoCode)
+{
+ return (notifyCB) ? notifyCB(this, userparam, eraseCode, primoCode) : ERASEMEDIUM_CONTINUE;
+}
+
+DWORD WINAPI EraseMedium::StatusThread(void* parameter)
+{
+ EraseMedium *object = (EraseMedium*)parameter;
+ DWORD current, total, waitResult;
+ object->errorCode = PRIMOSDK_RUNNING;
+ while(PRIMOSDK_RUNNING == object->errorCode && WAIT_TIMEOUT == (waitResult = WaitForSingleObject(object->evntStop, 1000)))
+ {
+ if (ERASEMEDIUM_STOP == object->OnNotify(ERASEMEDIUM_ERASING, PRIMOSDK_OK)) SetEvent(object->evntStop);
+ object->errorCode = object->primoSDK->RunningStatus(PRIMOSDK_GETSTATUS, &current, &total);
+ }
+ if (WAIT_OBJECT_0 == waitResult)
+ { // aborting
+ object->OnNotify(ERASEMEDIUM_CANCELING, PRIMOSDK_OK);
+ DWORD test = object->primoSDK->RunningStatus(PRIMOSDK_ABORT, &current, &total);
+ do
+ {
+ Sleep(1000);
+ object->errorCode = object->primoSDK->RunningStatus(PRIMOSDK_GETSTATUS, &current, &total);
+ }while(PRIMOSDK_RUNNING == object->errorCode);
+ }
+
+ if (PRIMOSDK_OK != object->errorCode && PRIMOSDK_USERABORT != object->errorCode)
+ {
+ object->OnNotify(ERASEMEDIUM_ERASEMEDIUMFAILED, object->errorCode);
+ }
+ // check unit status
+ DWORD cmd, sense, asc, ascq;
+ object->errorCode = object->primoSDK->UnitStatus(&object->bs.drive, &cmd, &sense, &asc, &ascq);
+ if (object->errorCode != PRIMOSDK_OK)
+ {
+ object->OnNotify(ERASEMEDIUM_ERASEMEDIUMFAILED, object->errorCode);
+ }
+
+ // end burn
+ object->bs.eject = object->eject;
+ object->OnNotify(ERASEMEDIUM_FINISHING, PRIMOSDK_OK);
+ DWORD errorCode2 = EndBurn(&object->bs);
+ if (PRIMOSDK_OK != errorCode2)
+ {
+ object->OnNotify(ERASEMEDIUM_ENDBURNFAILED, object->errorCode);
+ }
+ if (PRIMOSDK_OK == object->errorCode) object->errorCode = errorCode2;
+ object->primoSDK->Release();
+ CloseHandle(object->hThread);
+ object->hThread = NULL;
+ CloseHandle(object->evntStop);
+ object->evntStop = NULL;
+ object->OnNotify( (PRIMOSDK_USERABORT == object->errorCode) ? ERASEMEDIUM_ABORTED : ERASEMEDIUM_COMPLETED, object->errorCode);
+
+ if (object->evntThreadExit) SetEvent(object->evntThreadExit);
+ return object->errorCode;
+}
diff --git a/Src/burnlib/eraseMedium.h b/Src/burnlib/eraseMedium.h
new file mode 100644
index 00000000..ffd8cede
--- /dev/null
+++ b/Src/burnlib/eraseMedium.h
@@ -0,0 +1,68 @@
+#ifndef NULLSOFT_ERASEMEDIUM_HEADER
+#define NULLSOFT_ERASEMEDIUM_HEADER
+
+#include "./main.h"
+#include "./primosdk.h"
+
+#define ERASEMEDIUM_STATUS 0x0000
+#define ERASEMEDIUM_ERROR 0x1000
+
+// status messages
+#define ERASEMEDIUM_READY ((ERASEMEDIUM_STATUS) + 0x0001)
+#define ERASEMEDIUM_INITIALIZING ((ERASEMEDIUM_STATUS) + 0x0002)
+#define ERASEMEDIUM_ERASING ((ERASEMEDIUM_STATUS) + 0x0003)
+#define ERASEMEDIUM_FINISHING ((ERASEMEDIUM_STATUS) + 0x0004)
+#define ERASEMEDIUM_CANCELING ((ERASEMEDIUM_STATUS) + 0x0005)
+#define ERASEMEDIUM_COMPLETED ((ERASEMEDIUM_STATUS) + 0x0006)
+#define ERASEMEDIUM_ABORTED ((ERASEMEDIUM_STATUS) + 0x0007)
+
+
+// error messages
+#define ERASEMEDIUM_ALREADYSTARTED ((ERASEMEDIUM_ERROR) + 0x0001)
+#define ERASEMEDIUM_UNABLEINITPRIMO ((ERASEMEDIUM_ERROR) + 0x0002)
+#define ERASEMEDIUM_DEVICENOTREADY ((ERASEMEDIUM_ERROR) + 0x0003)
+#define ERASEMEDIUM_DISCINFOERROR ((ERASEMEDIUM_ERROR) + 0x0004)
+#define ERASEMEDIUM_DISCNOTERASABLE ((ERASEMEDIUM_ERROR) + 0x0005)
+#define ERASEMEDIUM_BEGINBURNFAILED ((ERASEMEDIUM_ERROR) + 0x0006)
+#define ERASEMEDIUM_ENDBURNFAILED ((ERASEMEDIUM_ERROR) + 0x0007)
+#define ERASEMEDIUM_ERASEMEDIUMFAILED ((ERASEMEDIUM_ERROR) + 0x0008)
+
+// callback returns
+#define ERASEMEDIUM_CONTINUE 0
+#define ERASEMEDIUM_STOP 1
+
+
+typedef DWORD (WINAPI *ERASEMEDIUMCALLBACK)(void*, void*, DWORD, DWORD);
+
+class EraseMedium
+{
+public:
+ BURNLIB_API EraseMedium(void);
+ BURNLIB_API ~EraseMedium(void);
+
+public:
+ BURNLIB_API DWORD Start(DWORD drive, DWORD eraseMode, ERASEMEDIUMCALLBACK notifyCB, void *userParam, int block);
+ BURNLIB_API void Stop(void);
+ BURNLIB_API DWORD GetErrorCode(void) { return errorCode; }
+ BURNLIB_API BOOL IsRunning(void) { return (NULL != hThread); }
+
+public:
+ BURNLIB_API DWORD SetEject(DWORD eject);
+protected:
+ DWORD OnNotify(DWORD eraseCode, DWORD primoCode);
+ static DWORD WINAPI StatusThread(void* parameter);
+
+protected:
+ WABURNSTRUCT bs;
+ obj_primo *primoSDK;
+ unsigned int eject;
+ HANDLE hThread;
+ HANDLE evntStop;
+ HANDLE evntThreadExit;
+ DWORD errorCode;
+ void* userparam;
+
+ ERASEMEDIUMCALLBACK notifyCB;
+};
+
+#endif //NULLSOFT_ERASEMEDIUM_HEADER
diff --git a/Src/burnlib/item.cpp b/Src/burnlib/item.cpp
new file mode 100644
index 00000000..bd3122f3
--- /dev/null
+++ b/Src/burnlib/item.cpp
@@ -0,0 +1,252 @@
+#include "./item.h"
+#include <strsafe.h>
+
+#define DECODEBUFFER_SIZE 4096*4
+
+DWORD BurnerItem::zeroMem[] = {0x00,};
+
+BurnerItem::BurnerItem(void)
+{
+ fullname = NULL;
+ title = NULL;
+ length = 0;
+ sizeBytes = 0;
+ sizeSectors = 0;
+ preGap = 0;
+ fposition = 0;
+ fhandle = NULL;
+ heap = GetProcessHeap();
+ ZeroMemory(ISRC, 12);
+ itemStatus = BURNERITEM_READY;
+ percentCompleted = 0;
+ errorCode = BURNERITEM_SUCCESS;
+ if (zeroMem[0] == 0x00) FillMemory(zeroMem, ZEROMEM_SIZE, 0xFFFFFFFF);
+
+}
+
+BurnerItem::~BurnerItem(void)
+{
+ Destroy();
+}
+
+HRESULT BurnerItem::Create(const wchar_t* fullname, const wchar_t *title, int length)
+{
+ if (this->fullname)
+ {
+ errorCode = BURNERITEM_ALREADYCREATED;
+ return errorCode;
+ }
+ this->fullname = DuplicateString(heap, fullname, lstrlenW(fullname));
+ this->title = DuplicateString(heap, title, lstrlenW(title));
+ this->length = length;
+ itemStatus = BURNERITEM_READY;
+ errorCode = BURNERITEM_SUCCESS;
+ return errorCode;
+}
+
+void BurnerItem::Destroy(void)
+{
+ if (fullname)
+ {
+ HeapFree(heap, NULL, fullname);
+ fullname = NULL;
+ }
+ if (title)
+ {
+ HeapFree(heap, NULL, title);
+ title = NULL;
+ }
+
+ length = 0;
+ sizeBytes = 0;
+ sizeSectors = 0;
+ preGap = 0;
+ fposition = 0;
+ fhandle = NULL;
+ ZeroMemory(ISRC, 12);
+
+}
+
+HRESULT BurnerItem::Decode(BurnManager *manager, void *fileHandle, BURNERITEMCALLBACK notifyCB, void *userparam)
+{
+ itemStatus = BURNERITEM_DECODING;
+ if (notifyCB) notifyCB(this, userparam, BURNERITEM_DECODESTARTING, BURNERITEM_SUCCESS);
+ if (!fullname)
+ {
+ errorCode = BURNERITEM_BADFILENAME;
+ itemStatus = BURNERITEM_DECODED;
+ if (notifyCB) notifyCB(this, userparam, BURNERITEM_DECODEFINISHED, errorCode);
+
+ return errorCode;
+ }
+
+ ifc_audiostream *stream = manager->CreateDecoder(fullname);
+ if (!stream)
+ {
+ errorCode = BURNERITEM_UNABLEOPENFILE;
+ itemStatus = BURNERITEM_DECODED;
+ if (notifyCB) notifyCB(this, userparam, BURNERITEM_DECODEFINISHED, errorCode);
+ return errorCode;
+ }
+
+ fposition = 0;
+ LONG fposLow(0), fposHigh(0);
+ fposLow = SetFilePointer(fileHandle, 0, &fposHigh, FILE_CURRENT);
+ fposition = (((__int64)fposHigh) << 32) | fposLow;
+ DWORD decoded = 0;
+ sizeBytes = 0;
+ sizeSectors = 0;
+ double percent = 0.0;
+ int iopercent = -1;
+ percentCompleted = 0;
+
+ errorCode = BURNERITEM_DECODEPROGRESS;
+ do
+ {
+ unsigned __int8 buffer[DECODEBUFFER_SIZE] = {0};
+ int decode_killswitch=0, decode_error;
+ decoded = (DWORD)stream->ReadAudio(buffer, DECODEBUFFER_SIZE, &decode_killswitch, &decode_error);
+ if (decoded > 0)
+ {
+ DWORD written = 0;
+ if (!WriteFile(fileHandle, buffer, decoded, &written, NULL))
+ {
+ errorCode = BURNERITEM_WRITEERROR;
+ break;
+ }
+ sizeBytes += decoded;
+ double step = ((double)decoded) / (((double)length) * 176.4f)*100.0f;
+ percent += step;
+ percentCompleted = (int)percent;
+ if (iopercent != percentCompleted)
+ {
+ iopercent = percentCompleted;
+ if (notifyCB)
+ {
+ if (BURNERITEM_CONTINUE != notifyCB(this, userparam, BURNERITEM_DECODEPROGRESS, percentCompleted))
+ {
+ errorCode = BURNERITEM_DECODECANCELING;
+ break;
+ }
+ }
+
+ }
+ }
+ } while(decoded);
+ if (stream) manager->CloseDecoder(stream);
+ itemStatus = BURNERITEM_DECODED;
+ DWORD notifyCode = BURNERITEM_DECODEFINISHED;
+ switch(errorCode)
+ {
+ case BURNERITEM_DECODECANCELING:
+ errorCode = BURNERITEM_ABORTED;
+ itemStatus = BURNERITEM_ABORTED;
+ break;
+ case BURNERITEM_DECODEPROGRESS:
+ sizeSectors = (DWORD)(sizeBytes/2352 + ((sizeBytes%2352) ? 1 : 0));
+ errorCode = BURNERITEM_SUCCESS;
+ break;
+ }
+ if (notifyCB) notifyCB(this, userparam, notifyCode, errorCode);
+ return errorCode;
+}
+
+
+HRESULT BurnerItem::AddStream(obj_primo *primoSDK, void *fileHandle)
+{
+ fhandle = fileHandle;
+ needSetFilePos = TRUE;
+ streamedSize = 0;
+
+ errorCode = primoSDK->AddAudioStream(StreamFiller, this, 0, GetSizeInSectors());
+ return errorCode;
+}
+void BurnerItem::SetPreGap(unsigned int preGap)
+{
+ this->preGap = preGap;
+}
+void BurnerItem::SetISRC(unsigned __int8 *ISRC)
+{
+ CopyMemory(this->ISRC, ISRC, 12);
+}
+
+int BurnerItem::GetStatus(DWORD *retCode)
+{
+ if(retCode)
+ {
+ switch(itemStatus)
+ {
+ case BURNERITEM_DECODING:
+ case BURNERITEM_BURNING:
+ *retCode = percentCompleted;
+ break;
+ default:
+ *retCode = errorCode;
+ }
+ }
+ return itemStatus;
+}
+
+DWORD BurnerItem::StreamFiller(PBYTE pBuffer, DWORD dwBytesRequested, PDWORD pdwBytesWritten, PVOID pContext)
+{
+ BurnerItem *item = (BurnerItem*) pContext;
+
+ if (item->needSetFilePos)
+ {
+ LONG fposLow = (LONG) item->fposition;
+ LONG fposHigh = (LONG) (item->fposition >> 32);
+ SetFilePointer(item->fhandle, fposLow, &fposHigh, FILE_BEGIN);
+ item->streamedSize = 0;
+ item->needSetFilePos = FALSE;
+ }
+
+ DWORD needToRead;
+ item->streamedSize += dwBytesRequested;
+ // check if we need to fill with zero
+ if (item->streamedSize > item->sizeBytes)
+ {
+ needToRead = (DWORD)min(0, ((long)item->sizeBytes) - long(item->streamedSize - dwBytesRequested));
+ }
+ else
+ {
+ needToRead = dwBytesRequested;
+ }
+ // read from file
+ if (needToRead)
+ {
+ *pdwBytesWritten = 0;
+ if (!ReadFile(item->fhandle, pBuffer, needToRead, pdwBytesWritten, NULL))
+ {
+ DWORD le = GetLastError();
+ item->itemStatus = BURNERITEM_BURNED;
+ item->errorCode = BURNERITEM_READSTREAMERROR;
+ }
+ //else
+ //{
+ // LONG fposLow(0), fposHigh(0);
+ // fposLow = SetFilePointer(item->fhandle, 0, &fposHigh, FILE_CURRENT);
+ // SetFilePointer(item->fhandle, -((LONG)*pdwBytesWritten), NULL, FILE_CURRENT);
+ // DWORD written(0);
+ // long needToZerro(*pdwBytesWritten)l
+ // while(needToZerro > 0)
+ // {
+ // DWORD write = min(ZEROMEM_SIZE*sizeof(DWORD), needToZerro);
+ // if (!WriteFile(item->fhandle, &zeroMem, write, &written, NULL)) break;
+ // needToZerro -= written;
+ // }
+ // SetFilePointer(item->fhandle, fposLow, &fposHigh, FILE_BEGIN);
+ //}
+ }
+ else
+ {
+ *pdwBytesWritten = 0;
+ }
+ return (BURNERITEM_SUCCESS == item->errorCode) ? PRIMOSDK_OK : PRIMOSDK_ERROR;
+}
+wchar_t* BurnerItem::DuplicateString(void *heap, const wchar_t *source, unsigned int cchSource)
+{
+ wchar_t *dest = (wchar_t*) HeapAlloc(heap, NULL, (cchSource + 1) * sizeof(wchar_t));
+ CopyMemory(dest, source, cchSource * sizeof(wchar_t));
+ dest[cchSource] = 0x0000;
+ return dest;
+} \ No newline at end of file
diff --git a/Src/burnlib/item.h b/Src/burnlib/item.h
new file mode 100644
index 00000000..73abb403
--- /dev/null
+++ b/Src/burnlib/item.h
@@ -0,0 +1,105 @@
+#pragma once
+
+#include "./main.h"
+#include "../Agave/DecodeFile/api_decodefile.h"
+#include "../Agave/DecodeFile/ifc_audiostream.h"
+#include "./manager.h"
+//#include "../primo/obj_primo.h"
+
+
+#define BURNERITEM_SUCCESS 0x0000
+
+#define BURNERITEM_STATUS 0x0000
+#define BURNERITEM_ERROR 0x1000
+
+// states
+
+#define BURNERITEM_SKIPPED 0x0100
+#define BURNERITEM_READY 0x0101
+#define BURNERITEM_LICENSING 0x0102
+#define BURNERITEM_LICENSED 0x0103
+#define BURNERITEM_DECODING 0x0104
+#define BURNERITEM_DECODED 0x0105
+#define BURNERITEM_BURNING 0x0106
+#define BURNERITEM_BURNED 0x0107
+
+// error codes
+#define BURNERITEM_FAILED ((BURNERITEM_ERROR) + 0x001)
+#define BURNERITEM_BADFILENAME ((BURNERITEM_ERROR) + 0x002)
+#define BURNERITEM_UNABLEOPENFILE ((BURNERITEM_ERROR) + 0x003)
+#define BURNERITEM_WRITEERROR ((BURNERITEM_ERROR) + 0x004)
+#define BURNERITEM_DECODEERROR ((BURNERITEM_ERROR) + 0x005)
+#define BURNERITEM_ALREADYCREATED ((BURNERITEM_ERROR) + 0x006)
+#define BURNERITEM_ADDSTREAMFAILED ((BURNERITEM_ERROR) + 0x007)
+#define BURNERITEM_READSTREAMERROR ((BURNERITEM_ERROR) + 0x008)
+#define BURNERITEM_ABORTED ((BURNERITEM_ERROR) + 0x009)
+#define BURNERITEM_CANCELING ((BURNERITEM_ERROR) + 0x00A)
+
+// statuses
+#define BURNERITEM_DECODESTARTING ((BURNERITEM_STATUS) + 0x001)
+#define BURNERITEM_DECODEPROGRESS ((BURNERITEM_STATUS) + 0x002)
+#define BURNERITEM_DECODECANCELING ((BURNERITEM_STATUS) + 0x003)
+#define BURNERITEM_DECODEFINISHED ((BURNERITEM_STATUS) + 0x004)
+
+
+
+// callback returns
+#define BURNERITEM_CONTINUE 0
+#define BURNERITEM_STOP 1
+
+
+typedef DWORD (WINAPI *BURNERITEMCALLBACK)(void*, void*, DWORD, DWORD); // sender, parameter, notifyCode, errorCode
+
+#define ZEROMEM_SIZE 1024
+class BurnerItem
+{
+ friend class BurnerPlaylist;
+public:
+
+ BURNLIB_API BurnerItem(void);
+ BURNLIB_API ~BurnerItem(void);
+
+public:
+ BURNLIB_API HRESULT Create(const wchar_t *fullname, const wchar_t *title, int length);
+ BURNLIB_API void Destroy(void);
+ BURNLIB_API HRESULT Decode(BurnManager *manager, void *fileHandle, BURNERITEMCALLBACK notifyCB, void *userparam);
+ BURNLIB_API HRESULT AddStream(obj_primo *primoSDK, void *fileHandle);
+
+public:
+ BURNLIB_API const wchar_t* GetFullName(void) { return fullname; }
+ BURNLIB_API const wchar_t* GetTitle(void) { return title; }
+ BURNLIB_API int GetLength(void) { return length; }
+ BURNLIB_API unsigned __int64 GetSize(void) { return sizeBytes; }
+ BURNLIB_API DWORD GetSizeInSectors(void) { return sizeSectors; }
+ BURNLIB_API unsigned int GetPreGap(void) { return preGap; }
+ BURNLIB_API unsigned __int8* GetISRC(void) { return ISRC; }
+ BURNLIB_API __int64 GetDecodedFilePosition(void) { return fposition; }
+ BURNLIB_API int GetStatus(DWORD *retCode); // if retCode not NULL - can return completed percentage or error code
+ void SetPreGap(unsigned int preGap);
+ void SetISRC(unsigned __int8 *ISRC);
+
+protected:
+ static wchar_t* DuplicateString(void *heap, const wchar_t *source, unsigned int cchSource);
+ static DWORD StreamFiller(PBYTE pBuffer, DWORD dwBytesRequested, PDWORD pdwBytesWritten, PVOID pContext);
+
+
+protected:
+ void *heap;
+ wchar_t *fullname;
+ wchar_t *title;
+ int length;
+ unsigned __int64 sizeBytes;
+ DWORD sizeSectors;
+ unsigned int preGap;
+ unsigned __int8 ISRC[12];
+ void* fhandle;
+ __int64 fposition;
+ BOOL needSetFilePos;
+ unsigned __int64 streamedSize;
+ int percentCompleted;
+ int itemStatus;
+ DWORD errorCode;
+ static DWORD zeroMem[ZEROMEM_SIZE];
+
+
+}; \ No newline at end of file
diff --git a/Src/burnlib/main.cpp b/Src/burnlib/main.cpp
new file mode 100644
index 00000000..ad12f280
--- /dev/null
+++ b/Src/burnlib/main.cpp
@@ -0,0 +1,24 @@
+// burnlib.cpp : Defines the entry point for the DLL application.
+//
+
+#include "main.h"
+
+extern api_service *serviceManager;
+api_language *WASABI_API_LNG_BURN = 0;
+HINSTANCE dllInstance = NULL;
+HMODULE hResource = NULL;
+HWND winampWnd = NULL;
+
+// must be first call before you start using library
+void InitializeBurningLibrary(api_service *wasabiServiceManager, HINSTANCE _dllInstance, HWND _winampWnd)
+{
+ dllInstance = _dllInstance;
+ serviceManager = wasabiServiceManager;
+ winampWnd = _winampWnd;
+
+ waServiceFactory *sf = serviceManager->service_getServiceByGuid(languageApiGUID);
+ if (sf) WASABI_API_LNG_BURN = reinterpret_cast<api_language*>(sf->getInterface());
+
+ // need to have this initialised before we try to do anything with localisation features
+ hResource = WASABI_API_LNG_BURN->StartLanguageSupport(LoadLibraryW(L"burnlib.dll"),burnlibLangGUID);
+} \ No newline at end of file
diff --git a/Src/burnlib/main.h b/Src/burnlib/main.h
new file mode 100644
index 00000000..2daa3d50
--- /dev/null
+++ b/Src/burnlib/main.h
@@ -0,0 +1,30 @@
+#pragma once
+
+#include <windows.h>
+
+#ifdef BURNLIB_EXPORTS
+ #define BURNLIB_API //__declspec(dllexport)
+#else
+ #define BURNLIB_API //__declspec(dllimport)
+#endif
+
+extern HINSTANCE dllInstance;
+extern HMODULE hResource;
+extern HWND winampWnd;
+
+#include <api/service/api_service.h>
+#include <api/service/waServiceFactory.h>
+#include "../Agave/Language/api_language.h"
+#include "./primosdk.h"
+//library Initialization
+BURNLIB_API void InitializeBurningLibrary(api_service *wasabiServiceManager, HINSTANCE, HWND);
+
+// text values (englsih)
+BURNLIB_API wchar_t* GetMediumText(wchar_t *buffer, unsigned int cchBuffer, DWORD medium);
+BURNLIB_API wchar_t* GetMediumTypeText(wchar_t *buffer, unsigned int cchBuffer, DWORD type);
+BURNLIB_API wchar_t* GetMediumFormatText(wchar_t *buffer, unsigned int cchBuffer, DWORD format);
+BURNLIB_API wchar_t* GetUnitStatusText(wchar_t *buffer, unsigned int cchBuffer, DWORD sense, DWORD asc, DWORD ascq);
+BURNLIB_API wchar_t* GetTrackTypeText(wchar_t *buffer, unsigned int cchBuffer, DWORD trackType);
+BURNLIB_API wchar_t* GetPrimoCodeText(wchar_t *buffer, unsigned int cchBuffer, DWORD primoCode);
+BURNLIB_API wchar_t* GetBussText(wchar_t *buffer, unsigned int cchBuffer, DWORD bussType);
+wchar_t* GetTimeString(wchar_t *string, unsigned int cchLen, unsigned int timesec); \ No newline at end of file
diff --git a/Src/burnlib/manager.h b/Src/burnlib/manager.h
new file mode 100644
index 00000000..743f0ec9
--- /dev/null
+++ b/Src/burnlib/manager.h
@@ -0,0 +1,42 @@
+#pragma once
+
+#include "../Agave/DecodeFile/ifc_audiostream.h"
+#include "../Agave/DecodeFile/api_decodefile.h"
+
+enum
+{
+ BURN_OK = 0, // OK to burn
+ BURN_GENERAL_FAILURE = 1, // can't burn, not 100% sure why
+ BURN_FILE_NOT_FOUND = 2, // file doesn't exist
+ BURN_DRM_NO_LICENSE = 3, // user doesn't have a license to open this DRM protected track
+ BURN_DRM_NOT_ALLOWED = 4, // DRM license disallows burning
+ BURN_DRM_BURN_COUNT_EXCEEDED= 5, // user has done too many burns already
+ BURN_NO_DECODER=6, // no decoder was found to decompress this file
+};
+typedef unsigned __int32 WRESULT;
+
+class BurnManagerCallback
+{
+public:
+ virtual void OnLicenseCallback(size_t numFiles, WRESULT *results) = 0;
+};
+
+class BurnManager
+{
+public:
+ BurnManager();
+ ~BurnManager();
+
+public:
+ void SetDecodeAPI(api_decodefile *decoderAPI);
+ api_decodefile *GetDecodeAPI(void);
+ void SetFiles(size_t numFiles, const wchar_t **filenames, BurnManagerCallback *callback);
+ ifc_audiostream *CreateDecoder(const wchar_t *filename);
+ void CloseDecoder(ifc_audiostream *decoder);
+ void CancelBurn();
+ void BurnFinished();
+
+private:
+ api_decodefile *decodeFile;
+ void *context; // pImpl (pointer to implementation)
+}; \ No newline at end of file
diff --git a/Src/burnlib/playlist.cpp b/Src/burnlib/playlist.cpp
new file mode 100644
index 00000000..56e32a43
--- /dev/null
+++ b/Src/burnlib/playlist.cpp
@@ -0,0 +1,686 @@
+#include "./playlist.h"
+#include "../Agave/DecodeFile/ifc_audiostream.h"
+#include <strsafe.h>
+#include "../winamp/wa_ipc.h"
+
+BurnerPlaylist::BurnerPlaylist()
+{
+ evntCancel = NULL;
+}
+
+BurnerPlaylist::~BurnerPlaylist()
+{
+ if (manager.GetDecodeAPI())
+ {
+ waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid(decodeFileGUID);
+ factory->releaseInterface(manager.GetDecodeAPI());
+ manager.SetDecodeAPI(NULL);
+ }
+ clear();
+}
+
+HRESULT BurnerPlaylist::Load(const wchar_t *filename)
+{
+ if (!WASABI_API_SVC) return PLAYLISTMANAGER_FAILED;
+ waServiceFactory *plmFactory = WASABI_API_SVC->service_getServiceByGuid(api_playlistmanagerGUID);
+ if (!plmFactory) return 0;
+ api_playlistmanager *plManager = (api_playlistmanager*)plmFactory->getInterface();
+ if (!plManager) return 0;
+ length = 0;
+ int retCode = plManager->Load(filename, this);
+ return (PLAYLISTMANAGER_SUCCESS == retCode);
+}
+
+DWORD BurnerPlaylist::GetTotalSectors(void)
+{
+ DWORD ts = 0;
+ for(size_t i = 0; i < GetCount(); i++)
+ {
+ ts += BurnerVector::at(i)->GetSizeInSectors();
+ }
+ return ts;
+}
+DWORD BurnerPlaylist::GetStatus(DWORD *retCode)
+{
+ if(retCode) *retCode = errorCode;
+ return statusCode;
+}
+
+size_t BurnerPlaylist::GetStateCount(DWORD state, DWORD code)
+{
+ size_t count = 0;
+ for (size_t i = 0; i < GetCount(); i++)
+ {
+ if (BurnerVector::at(i)->itemStatus == state && BurnerVector::at(i)->errorCode == code) count++;
+ }
+ return count;
+}
+
+DWORD BurnerPlaylist::GetStateLengthMS(DWORD state, DWORD code)
+{
+ DWORD len = 0;
+ for (size_t i = 0; i < GetCount(); i++)
+ {
+ if (BurnerVector::at(i)->itemStatus == state && BurnerVector::at(i)->errorCode == code) len += BurnerVector::at(i)->GetLength();
+ }
+ return len;
+}
+
+DWORD BurnerPlaylist::GetStateSectors(DWORD state, DWORD code)
+{
+ DWORD ts = 0;
+ for(size_t i = 0; i < GetCount(); i++)
+ {
+ if (BurnerVector::at(i)->itemStatus == state && BurnerVector::at(i)->errorCode == code) ts += BurnerVector::at(i)->GetSizeInSectors();
+ }
+ return ts;
+}
+
+HRESULT BurnerPlaylist::CheckLicense(BURNERPLAYLISTCALLBACK notifyCB, void *userparam)
+{
+ this->notifyCB = notifyCB;
+ this->userparam = userparam;
+
+ statusCode = BURNERPLAYLIST_LICENSINGSTARTING;
+ errorCode = BURNERPLAYLIST_SUCCESS;
+ OnNotify(statusCode, errorCode, 0);
+
+ size_t count = BurnerVector::size();
+ size_t realCount = 0;
+ manager.CancelBurn(); // ha-ha
+ wchar_t **filenames = (count) ? (wchar_t**)malloc(count*sizeof(wchar_t*)) : NULL;
+ DWORD nc, ec;
+
+ for (size_t i = 0; i < count; i++)
+ {
+ nc = BurnerVector::at(i)->GetStatus(&ec);
+ if (nc == BURNERITEM_READY ||
+ ((nc == BURNERITEM_LICENSED || nc == BURNERITEM_DECODED) && ec == BURNERITEM_SUCCESS))
+ {
+ filenames[realCount] = (wchar_t*)BurnerVector::at(i)->GetFullName();
+ BurnerVector::at(i)->itemStatus = BURNERITEM_LICENSING;
+ errorCode = BURNERPLAYLIST_ITEMADDED;
+ realCount++;
+ }
+ else
+ {
+ BurnerVector::at(i)->itemStatus = BURNERITEM_SKIPPED;
+ errorCode = BURNERPLAYLIST_ADDITEMSKIPPED;
+ }
+ OnNotify(statusCode, errorCode, i);
+ }
+ if (realCount == 0)
+ {
+ statusCode = BURNERPLAYLIST_LICENSINGFINISHED;
+ errorCode = BURNERPLAYLIST_NOFILES;
+ OnNotify(statusCode, errorCode, 0);
+ if (filenames) free(filenames);
+ return statusCode;
+ }
+ if (!manager.GetDecodeAPI())
+ {
+ api_decodefile *decoder = NULL;
+ waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid(decodeFileGUID);
+ if (factory) decoder = (api_decodefile *)factory->getInterface();
+ if (!factory || !decoder)
+ {
+ statusCode = BURNERPLAYLIST_LICENSINGFINISHED;
+ errorCode = BURNERPLAYLIST_DECODESERVICEFAILED;
+ OnNotify(statusCode, errorCode, 0);
+ free(filenames);
+ return statusCode;
+ }
+ manager.SetDecodeAPI(decoder);
+ }
+
+ manager.SetFiles(realCount, (const wchar_t**)filenames, this);
+ free(filenames);
+ return statusCode;
+}
+
+HRESULT BurnerPlaylist::Decode(void* hFile, BURNERPLAYLISTCALLBACK notifyCB, void *userparam, BOOL block)
+{
+ this->notifyCB = notifyCB;
+ this->userparam = userparam;
+ this->hFile = hFile;
+ hThread = NULL;
+
+ statusCode = BURNERPLAYLIST_DECODESTARTING;
+ errorCode = BURNERPLAYLIST_SUCCESS;
+ OnNotify(statusCode, errorCode, 0);
+
+ if (!manager.GetDecodeAPI())
+ {
+ api_decodefile *decoder = NULL;
+ waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid(decodeFileGUID);
+ if (factory) decoder = (api_decodefile *)factory->getInterface();
+ if (!factory || !decoder)
+ {
+ statusCode = BURNERPLAYLIST_DECODEFINISHED;
+ errorCode = BURNERPLAYLIST_DECODESERVICEFAILED;
+ OnNotify(statusCode, errorCode, 0);
+ return statusCode;
+ }
+ manager.SetDecodeAPI(decoder);
+ }
+
+ if (block)
+ {
+ statusCode = DecodeWorker(this);
+ OnNotify(statusCode, errorCode, 100);
+ if (manager.GetDecodeAPI())
+ {
+ waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid(decodeFileGUID);
+ factory->releaseInterface(manager.GetDecodeAPI());
+ manager.SetDecodeAPI(NULL);
+ }
+
+ }
+ else
+ {
+ DWORD id;
+ hThread = CreateThread(NULL, 0, DecodeWorker, this, 0, &id);
+ if (NULL == hThread)
+ {
+ statusCode = BURNERPLAYLIST_DECODEFINISHED;
+ errorCode = BURNERPLAYLIST_THREADCREATEFAILED;
+ OnNotify(statusCode, errorCode, 0);
+ }
+ }
+ return statusCode;
+}
+
+HRESULT BurnerPlaylist::Burn(obj_primo *primoSDK, DWORD drive, DWORD maxspeed, DWORD burnFlags, void* hFile,
+ BURNERPLAYLISTCALLBACK notifyCB, void *userparam, BOOL block)
+{
+ this->primoSDK = primoSDK;
+ this->drive = drive;
+ this->hFile = hFile;
+ this->maxspeed = maxspeed;
+ this->burnFlags = burnFlags;
+ this->notifyCB = notifyCB;
+ this->userparam = userparam;
+ statusCode = BURNERPLAYLIST_BURNSTARTING;
+ errorCode = BURNERPLAYLIST_SUCCESS;
+ evntCancel = CreateEvent(NULL, FALSE, FALSE, NULL);
+ OnNotify(statusCode, errorCode, 0); // here we go
+
+ DWORD retCode;
+ DWORD dwUnits[2];
+ dwUnits[0] = drive;
+ dwUnits[1] = 0xFFFFFFFF;
+ retCode = primoSDK->NewAudio(dwUnits);
+ if (PRIMOSDK_OK != retCode)
+ {
+ statusCode = BURNERPLAYLIST_BURNFINISHED;
+ errorCode = BURNERPLAYLIST_NEWAUDIOFAILED;
+ OnNotify(statusCode, errorCode, retCode);
+ return statusCode;
+ }
+
+ if (BurnerVector::size() == 0)
+ {
+ statusCode = BURNERPLAYLIST_BURNFINISHED;
+ errorCode = BURNERPLAYLIST_NOFILES;
+ OnNotify(statusCode, errorCode, retCode);
+ return statusCode;
+ }
+ size_t i;
+ for(i = 0; i < BurnerVector::size(); i++)
+ {
+ DWORD ec;
+ if (BURNERITEM_DECODED == BurnerVector::at(i)->GetStatus(&ec) && BURNERITEM_SUCCESS == ec)
+ {
+ BurnerVector::at(i)->itemStatus = BURNERITEM_READY;
+ retCode = BurnerVector::at(i)->AddStream(primoSDK, hFile);
+ if (PRIMOSDK_OK != retCode)
+ {
+ BurnerVector::at(i)->itemStatus = BURNERITEM_BURNED;
+ BurnerVector::at(i)->errorCode = BURNERITEM_FAILED;
+ errorCode = BURNERPLAYLIST_ADDITEMFAILED;
+ break;
+ }
+ else errorCode = BURNERPLAYLIST_ITEMADDED;
+ }
+ else
+ {
+ errorCode = BURNERPLAYLIST_ADDITEMSKIPPED;
+ BurnerVector::at(i)->itemStatus = BURNERITEM_SKIPPED;
+ }
+ OnNotify(statusCode, errorCode, i);
+
+ }
+
+ if (PRIMOSDK_OK != retCode || (WAIT_OBJECT_0 == WaitForSingleObject(evntCancel, 0)))
+ {
+
+ statusCode = (PRIMOSDK_OK == retCode) ? BURNERPLAYLIST_BURNCANCELING : BURNERPLAYLIST_BURNFINISHING;
+ errorCode = (PRIMOSDK_OK == retCode) ? BURNERPLAYLIST_ABORTED : BURNERPLAYLIST_ADDITEMFAILED;
+ BPLRUNSTATUS burnStatus;
+
+ for(i = 0; i < BurnerVector::size(); i++)
+ {
+ burnStatus.iIndex = (int)i;
+ if (BURNERITEM_SKIPPED == BurnerVector::at(burnStatus.iIndex)->itemStatus) continue;
+
+ BurnerVector::at(burnStatus.iIndex)->itemStatus = (PRIMOSDK_OK == retCode) ? BURNERITEM_ABORTED : BURNERITEM_FAILED;
+ OnNotify(statusCode, errorCode, (ULONG_PTR)&burnStatus);
+ }
+
+ CloseHandle(evntCancel);
+ evntCancel = NULL;
+ primoSDK->CloseAudio();
+ statusCode = BURNERPLAYLIST_BURNFINISHED;
+ OnNotify(statusCode, errorCode, i);
+ return statusCode;
+ }
+
+ if (block)
+ {
+ DWORD notifyCode = BurnerWorker(this);
+ OnNotify(BURNERPLAYLIST_BURNFINISHED, notifyCode, errorCode);
+ }
+ else
+ {
+ DWORD id;
+ hThread = CreateThread(NULL, 0, BurnerWorker, this, 0, &id);
+ if (NULL == hThread)
+ {
+ statusCode = BURNERPLAYLIST_BURNFINISHED;
+ errorCode = BURNERPLAYLIST_THREADCREATEFAILED;
+ OnNotify(statusCode, errorCode, i);
+ }
+ }
+
+ return statusCode;
+}
+
+DWORD BurnerPlaylist::AddCompilationToCDDB(void)
+{
+ wchar_t buf[64] = {0};
+ wchar_t albumbuf[256]= L"Mix CD ";
+
+ wchar_t dateString[128] = {0};
+ GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOTIMEMARKER, NULL, NULL, dateString, 128);
+ StringCchCatW(albumbuf, 256, dateString);
+
+ StringCchPrintfW(buf, 64, L"cda://%c.cda", (char)drive);
+ extendedFileInfoStructW efis = { buf, L"album", albumbuf, 256, };
+
+ if (SendMessageW(winampWnd, WM_WA_IPC, (WPARAM)&efis, IPC_SET_EXTENDED_FILE_INFOW))
+ {
+ efis.metadata = L"albumartist";
+ efis.ret = L"Various Artists";
+ SendMessageW(winampWnd, WM_WA_IPC, (WPARAM)&efis, IPC_SET_EXTENDED_FILE_INFOW);
+ efis.metadata = L"genre";
+ efis.ret = L"Mix";
+ SendMessageW(winampWnd, WM_WA_IPC, (WPARAM)&efis, IPC_SET_EXTENDED_FILE_INFOW);
+ SYSTEMTIME syst;
+ GetLocalTime(&syst);
+ if (syst.wYear)
+ {
+ wchar_t yearbuf[64] = {0};
+ StringCchPrintfW(yearbuf, 64, L"%04d", syst.wYear);
+ efis.metadata = L"year";
+ efis.ret = yearbuf;
+ SendMessageW(winampWnd, WM_WA_IPC, (WPARAM)&efis, IPC_SET_EXTENDED_FILE_INFOW);
+ }
+ wchar_t buf2[32] = {0};
+ int index = 1;
+ for (size_t i = 0;i < GetCount();i++)
+ {
+ DWORD is, ec;
+ is = BurnerVector::at(i)->GetStatus(&ec);
+ if (BURNERITEM_BURNED == is && BURNERITEM_SUCCESS == ec)
+ {
+ StringCchPrintfW(buf, 64, L"cda://%c,%d.cda", (char)drive, i);
+ lstrcpynW(buf2, L"title", 32);
+ efis.metadata = buf2;
+ efis.ret = const_cast<wchar_t*>(BurnerVector::at(i)->GetTitle());
+ SendMessageW(winampWnd, WM_WA_IPC, (WPARAM)&efis, IPC_SET_EXTENDED_FILE_INFOW);
+
+ lstrcpynW(buf2, L"artist", 32);
+ efis.ret=L"Various Artists"; // TODO: use actual track artist
+ SendMessageW(winampWnd, WM_WA_IPC, (WPARAM)&efis, IPC_SET_EXTENDED_FILE_INFOW);
+
+ index++;
+ }
+ }
+ SendMessageW(winampWnd, WM_WA_IPC, (WPARAM)0, IPC_WRITE_EXTENDED_FILE_INFO);
+ }
+ return 1;
+}
+DWORD WINAPI BurnerPlaylist::DecodeWorker(void* param)
+{
+ DWORD retCode;
+ BurnerPlaylist *playlist = (BurnerPlaylist*)param;
+
+ playlist->percentStep = (float)(1.f / ((double)playlist->GetCount()));
+ playlist->activeDecode = NULL;
+ DWORD itemError = BURNERITEM_SUCCESS;
+
+ // for nice ui reason lets do it twice
+ playlist->statusCode = BURNERPLAYLIST_DECODESTARTING;
+ for(size_t i = 0; i < playlist->GetCount(); i++)
+ {
+ DWORD ec;
+ if (BURNERITEM_LICENSED == playlist->at(i)->GetStatus(&ec) && BURN_OK == ec)
+ {
+ playlist->errorCode = BURNERPLAYLIST_ITEMADDED;
+ playlist->at(i)->itemStatus = BURNERITEM_READY;
+ }
+ else
+ {
+
+ playlist->errorCode = BURNERPLAYLIST_ADDITEMSKIPPED;
+ playlist->at(i)->itemStatus = BURNERITEM_SKIPPED;
+
+ }
+ playlist->OnNotify(playlist->statusCode, playlist->errorCode, i);
+ }
+
+ // actual work
+ for(size_t i = 0; i < playlist->GetCount(); i++)
+ {
+ if (BURNERITEM_READY == playlist->at(i)->GetStatus(NULL))
+ {
+ BPLDECODEINFO info;
+ info.iInstance = playlist->at(i);
+ info.iIndex = (int)i;
+ info.iNotifyCode = 0;
+ info.iErrorCode = 0;
+ info.percentCompleted = (playlist->activeDecode) ? playlist->percentStep*i*100.0f : 0;
+ playlist->activeDecode = &info;
+ playlist->statusCode = BURNERPLAYLIST_DECODEPROGRESS;
+ playlist->errorCode = BURNERPLAYLIST_DECODENEXTITEM;
+ playlist->OnNotify(playlist->statusCode, playlist->errorCode, (ULONG_PTR)playlist->activeDecode);
+ retCode = playlist->at(i)->Decode(&playlist->manager, playlist->hFile, OnItemDecode, playlist);
+ if (BURNERITEM_SUCCESS != retCode)
+ {
+ itemError = retCode;
+ }
+ if (BURNERITEM_ABORTED == retCode)
+ {
+ playlist->statusCode = BURNERPLAYLIST_DECODECANCELING;
+ playlist->errorCode = BURNERPLAYLIST_ABORTED;
+ DWORD notifyCode = BURNERITEM_DECODEFINISHED;
+ for(size_t k = i; k < playlist->GetCount(); k++)
+ {
+ info.iIndex = (int)k;
+ info.iInstance = playlist->at(k);
+ info.iInstance->errorCode = BURNERITEM_ABORTED;
+ info.iInstance->itemStatus = BURNERITEM_ABORTED;
+ OnItemDecode(info.iInstance, playlist, notifyCode, info.iInstance->errorCode);
+ }
+ break;
+ }
+ }
+ }
+
+ // release decoderAPI
+ waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid(decodeFileGUID);
+ factory->releaseInterface(playlist->manager.GetDecodeAPI());
+ playlist->manager.SetDecodeAPI(NULL);
+
+ if (playlist->hThread)
+ {
+ CloseHandle(playlist->hThread);
+ playlist->hThread = NULL;
+ }
+
+ playlist->statusCode = BURNERPLAYLIST_DECODEFINISHED;
+ if (playlist->GetCount() == 0) playlist->errorCode = BURNERPLAYLIST_NOFILES;
+ else if (BURNERITEM_ABORTED == itemError) playlist->errorCode = BURNERPLAYLIST_ABORTED;
+ else if (BURNERITEM_SUCCESS == itemError) playlist->errorCode = BURNERPLAYLIST_SUCCESS;
+ else playlist->errorCode = BURNERPLAYLIST_FAILED;
+
+ playlist->OnNotify(playlist->statusCode , playlist->errorCode, (ULONG_PTR)playlist->activeDecode);
+ playlist->activeDecode = NULL;
+ return playlist->statusCode;
+}
+DWORD WINAPI BurnerPlaylist::BurnerWorker(void* param)
+{
+ DWORD primoCode;
+ BurnerPlaylist *playlist = (BurnerPlaylist*)param;
+
+ WABURNSTRUCT bs;
+ playlist->statusCode = BURNERPLAYLIST_BURNSTARTING;
+ playlist->errorCode = BURNERPLAYLIST_BEGINBURN;
+ playlist->OnNotify(playlist->statusCode, playlist->errorCode, 0);
+ primoCode = BeginBurn(playlist->primoSDK, playlist->drive, &bs);
+ bs.eject = TRUE;
+ DWORD leadin = 0;
+ BPLRUNSTATUS burnStatus;
+ ZeroMemory(&burnStatus, sizeof(BPLRUNSTATUS));
+ burnStatus.iIndex = -1;
+
+ BOOL canceled = FALSE;
+ DWORD itemSector = 0;
+ BOOL cp1 = FALSE;
+ if (PRIMOSDK_OK != primoCode)
+ {
+ playlist->errorCode = BURNERPLAYLIST_BEGINBURNFAILED;
+ }
+ else
+ {
+ playlist->statusCode = BURNERPLAYLIST_BURNPROGRESS;
+ primoCode = playlist->primoSDK->WriteAudioEx(playlist->burnFlags, playlist->maxspeed, 0x00);
+ if (PRIMOSDK_OK == primoCode)
+ {
+ DWORD waitResult;
+ while(BURNERPLAYLIST_BURNPROGRESS == playlist->statusCode && WAIT_TIMEOUT == (waitResult = WaitForSingleObject(playlist->evntCancel, 500)))
+ {
+ primoCode = playlist->primoSDK->RunningStatus(PRIMOSDK_GETSTATUS, &burnStatus.sCurrent, &burnStatus.sTotal);
+ if (PRIMOSDK_RUNNING == primoCode)
+ {
+ playlist->statusCode = BURNERPLAYLIST_BURNPROGRESS;
+ if (burnStatus.sCurrent == 0)
+ {
+ if (cp1) continue; // do not send anymore
+ playlist->errorCode = BURNERPLAYLIST_WRITELEADIN; //BURNERPLAYLIST_DISCOPEN
+ cp1 = TRUE;
+ }
+ else if (burnStatus.sCurrent > 0 && (!leadin || leadin == burnStatus.sCurrent))
+ {
+ if (!leadin)
+ {
+ leadin = burnStatus.sCurrent;
+ playlist->errorCode = BURNERPLAYLIST_WRITELEADIN; // unreachable :)
+ }
+ continue;
+ }
+ else if (burnStatus.sCurrent == burnStatus.sTotal)
+ {
+ if (burnStatus.iIndex >= 0 && BURNERITEM_BURNING == playlist->at(burnStatus.iIndex)->itemStatus)
+ {
+ playlist->at(burnStatus.iIndex)->itemStatus = BURNERITEM_BURNED;
+ playlist->at(burnStatus.iIndex)->errorCode = BURNERITEM_SUCCESS;
+ playlist->at(burnStatus.iIndex)->percentCompleted = 100;
+ playlist->OnNotify(playlist->statusCode, BURNERPLAYLIST_WRITEITEMEND, (ULONG_PTR)&burnStatus);
+ }
+ if (burnStatus.iIndex == -1) continue;
+ playlist->errorCode = BURNERPLAYLIST_WRITELEADOUT;
+ burnStatus.iIndex = -1;
+ burnStatus.iInstance = NULL;
+
+ }
+ else
+ {
+ playlist->errorCode = BURNERPLAYLIST_WRITEDATA;
+ while (itemSector < burnStatus.sCurrent && burnStatus.iIndex < (int)playlist->size())
+ { if (burnStatus.iIndex >= 0 && BURNERITEM_BURNING == playlist->at(burnStatus.iIndex)->itemStatus)
+ {
+ playlist->at(burnStatus.iIndex)->itemStatus = BURNERITEM_BURNED;
+ playlist->at(burnStatus.iIndex)->errorCode = BURNERITEM_SUCCESS;
+ playlist->at(burnStatus.iIndex)->percentCompleted = 100;
+ playlist->OnNotify(playlist->statusCode, BURNERPLAYLIST_WRITEITEMEND, (ULONG_PTR)&burnStatus);
+ }
+ while (++burnStatus.iIndex < (int)playlist->size() && BURNERITEM_READY != playlist->at(burnStatus.iIndex)->itemStatus);
+ if (burnStatus.iIndex < (int)playlist->size()) itemSector += playlist->at(burnStatus.iIndex)->GetSizeInSectors();
+ }
+ if ( burnStatus.iIndex >= 0 && burnStatus.iIndex < (int)playlist->size())
+ {
+ BurnerItem *bi = playlist->at(burnStatus.iIndex);
+ burnStatus.iInstance = bi;
+ if (BURNERITEM_READY == bi->itemStatus)
+ {
+ bi->itemStatus = BURNERITEM_BURNING;
+ bi->percentCompleted = 0;
+ playlist->OnNotify(playlist->statusCode, BURNERPLAYLIST_WRITEITEMBEGIN, (ULONG_PTR)&burnStatus);
+ }
+ if (BURNERITEM_SUCCESS == bi->errorCode)
+ {
+ DWORD is = bi->GetSizeInSectors();
+ bi->itemStatus = BURNERITEM_BURNING;
+ bi->percentCompleted = (is - (itemSector - burnStatus.sCurrent))*100 / is;
+ }
+ else
+ {
+ bi->itemStatus = BURNERITEM_BURNED;
+ bi->errorCode = BURNERITEM_SUCCESS;
+ bi->percentCompleted = 100;
+ }
+ }
+
+ }
+ playlist->OnNotify(playlist->statusCode, playlist->errorCode, (ULONG_PTR)&burnStatus);
+ }
+ else
+ {
+ playlist->errorCode = BURNERPLAYLIST_WRITEAUDIOFAILED;
+ break;
+ }
+ }
+
+ if (WAIT_OBJECT_0 == waitResult)
+ { // aborting
+ canceled = TRUE;
+
+ playlist->statusCode = BURNERPLAYLIST_BURNCANCELING;
+ playlist->errorCode = BURNERPLAYLIST_ABORTED;
+ playlist->at(burnStatus.iIndex)->itemStatus = BURNERITEM_CANCELING;
+ playlist->OnNotify(playlist->statusCode, playlist->errorCode, (ULONG_PTR)&burnStatus);
+ DWORD test = playlist->primoSDK->RunningStatus(PRIMOSDK_ABORT, &burnStatus.sCurrent, &burnStatus.sTotal);
+ do
+ {
+ Sleep(1000);
+ primoCode = playlist->primoSDK->RunningStatus(PRIMOSDK_GETSTATUS, &burnStatus.sCurrent, &burnStatus.sTotal);
+ }while(PRIMOSDK_RUNNING == primoCode);
+ for (size_t i = 0; i < playlist->GetCount(); i++)
+ {
+ burnStatus.iIndex = (int)i;
+ DWORD cs = playlist->at(burnStatus.iIndex)->itemStatus;
+ if (BURNERITEM_BURNING != cs && BURNERITEM_READY != cs && BURNERITEM_CANCELING != cs) continue;
+ playlist->at(burnStatus.iIndex)->itemStatus = BURNERITEM_ABORTED;
+ playlist->OnNotify(playlist->statusCode, playlist->errorCode, (ULONG_PTR)&burnStatus);
+ }
+ }
+
+ }
+ else
+ {
+ playlist->errorCode = BURNERPLAYLIST_WRITEAUDIOFAILED;
+ }
+ }
+ if (PRIMOSDK_USERABORT == primoCode) playlist->errorCode = BURNERPLAYLIST_ABORTED;
+ else if (PRIMOSDK_OK == primoCode) playlist->errorCode = BURNERPLAYLIST_SUCCESS;
+ playlist->statusCode = BURNERPLAYLIST_BURNFINISHING;
+ playlist->OnNotify(playlist->statusCode, playlist->errorCode, 0);
+
+ // check unit status and notify later
+ DWORD statCode, cmd(0), sense(0), asc(0), ascq(0);
+ statCode = playlist->primoSDK->UnitStatus(&bs.drive, &cmd, &sense, &asc, &ascq);
+
+ bs.eject = playlist->ejectDone;
+
+ primoCode = EndBurn(&bs);
+
+ if (PRIMOSDK_OK != primoCode) playlist->errorCode = BURNERPLAYLIST_ENDBURNFAILED;
+
+ playlist->primoSDK->CloseAudio();
+
+ if (playlist->hThread)
+ {
+ CloseHandle(playlist->hThread);
+ playlist->hThread = NULL;
+ }
+ primoCode = (0xFF000000 & (statCode << 24)) | (0x00FF0000 & (sense << 16)) | (0x0000FF00 & (asc << 8)) | (0x000000FF & ascq);
+ if (BURNERPLAYLIST_SUCCESS == playlist->errorCode && statCode != PRIMOSDK_OK) playlist->errorCode = BURNERPLAYLIST_FAILED;
+
+ if (BURNERPLAYLIST_SUCCESS == playlist->errorCode && (PRIMOSDK_WRITE == (playlist->burnFlags&PRIMOSDK_WRITE)))
+ {
+ playlist->manager.BurnFinished();
+ }
+ else
+ {
+ playlist->manager.CancelBurn();
+ }
+
+ playlist->statusCode = BURNERPLAYLIST_BURNFINISHED;
+ playlist->OnNotify(playlist->statusCode, playlist->errorCode, primoCode);
+ return playlist->statusCode;
+}
+
+DWORD BurnerPlaylist::OnNotify(DWORD notifyCode, DWORD errorCode, ULONG_PTR param)
+{
+ DWORD retCode = (notifyCB) ? notifyCB(this, userparam, notifyCode, errorCode, param) : BURNERPLAYLIST_CONTINUE;
+ if ( BURNERPLAYLIST_STOP == retCode && evntCancel) SetEvent(evntCancel);
+ return retCode;
+}
+
+
+void BurnerPlaylist::OnFile(const wchar_t *filename, const wchar_t *title, int lengthInMS, ifc_plentryinfo *info)
+{
+ if (NULL == filename) return;
+ BurnerItem *item = new BurnerItem();
+ item->Create(filename,title, lengthInMS);
+ length += lengthInMS;
+ push_back(item);
+}
+
+DWORD WINAPI BurnerPlaylist::OnItemDecode(void* sender, void *param, DWORD notifyCode, DWORD errorCode)
+{
+ BurnerPlaylist *pl = (BurnerPlaylist*)param;
+ pl->activeDecode->iNotifyCode = notifyCode;
+ pl->activeDecode->iErrorCode = errorCode;
+ pl->activeDecode->percentCompleted += pl->percentStep;
+ pl->statusCode = BURNERPLAYLIST_DECODEPROGRESS;
+ pl->errorCode = BURNERPLAYLIST_DECODEITEM;
+ DWORD retCode = pl->OnNotify(pl->statusCode , pl->errorCode , (ULONG_PTR)pl->activeDecode);
+ return (BURNERPLAYLIST_STOP == retCode) ? BURNERITEM_STOP : BURNERITEM_CONTINUE;
+}
+
+void BurnerPlaylist::OnLicenseCallback(size_t numFiles, WRESULT *results)
+{
+ statusCode = BURNERPLAYLIST_LICENSINGPROGRESS;
+ DWORD errorCode = BURNERPLAYLIST_SUCCESS;
+ size_t realCount = 0;
+ size_t allowed = 0;
+ for (size_t i = 0; i < BurnerVector::size(); i++)
+ {
+ if (BURNERITEM_LICENSING == BurnerVector::at(i)->itemStatus)
+ {
+ if (realCount == numFiles)
+ {
+ statusCode = BURNERPLAYLIST_LICENSINGFINISHED;
+ errorCode = BURNERPLAYLIST_WRONGFILECOUNT;
+ break;
+ }
+ BurnerVector::at(i)->itemStatus = BURNERITEM_LICENSED;
+ BurnerVector::at(i)->errorCode = results[realCount];
+ OnNotify(statusCode, results[realCount], (LPARAM)i);
+ if (BURN_OK != results[realCount]) errorCode = BURNERPLAYLIST_FILENOTLICENSED;
+ else allowed++;
+ realCount++;
+ }
+
+ }
+ statusCode = BURNERPLAYLIST_LICENSINGFINISHED;
+ OnNotify(statusCode, errorCode, allowed);
+}
+
+#define CBCLASS BurnerPlaylist
+START_DISPATCH;
+VCB(IFC_PLAYLISTLOADERCALLBACK_ONFILE, OnFile)
+END_DISPATCH;
+#undef CBCLASS \ No newline at end of file
diff --git a/Src/burnlib/playlist.h b/Src/burnlib/playlist.h
new file mode 100644
index 00000000..218b68eb
--- /dev/null
+++ b/Src/burnlib/playlist.h
@@ -0,0 +1,157 @@
+#ifndef NULLSOFT_BurnerPlaylist_HEADER
+#define NULLSOFT_BurnerPlaylist_HEADER
+
+#include "./main.h"
+#include "./api.h"
+
+#include <api/service/waServiceFactory.h>
+#include "../playlist/api_playlistmanager.h"
+#include "../playlist/ifc_playlistloadercallback.h"
+#include "../winamp/api_decodefile.h"
+
+#include "../nu/vector.h"
+
+#include "./item.h"
+#include "./manager.h"
+
+#define BURNERPLAYLIST_SUCCESS 0x0000
+
+#define BURNERPLAYLIST_STATUS 0x0000
+#define BURNERPLAYLIST_ERROR 0x1000
+
+// error codes
+#define BURNERPLAYLIST_FAILED ((BURNERPLAYLIST_ERROR) + 0x001)
+#define BURNERPLAYLIST_BADFILENAME ((BURNERPLAYLIST_ERROR) + 0x002)
+#define BURNERPLAYLIST_UNABLEOPENFILE ((BURNERPLAYLIST_ERROR) + 0x003)
+#define BURNERPLAYLIST_WRITEERROR ((BURNERPLAYLIST_ERROR) + 0x004)
+#define BURNERPLAYLIST_DECODEERROR ((BURNERPLAYLIST_ERROR) + 0x005)
+#define BURNERPLAYLIST_DECODESERVICEFAILED ((BURNERPLAYLIST_ERROR) + 0x006)
+#define BURNERPLAYLIST_THREADCREATEFAILED ((BURNERPLAYLIST_ERROR) + 0x007)
+#define BURNERPLAYLIST_NOFILES ((BURNERPLAYLIST_ERROR) + 0x008)
+#define BURNERPLAYLIST_WRONGFILECOUNT ((BURNERPLAYLIST_ERROR) + 0x009)
+
+//
+#define BURNERPLAYLIST_ABORTED ((BURNERPLAYLIST_STATUS) +0x100)
+#define BURNERPLAYLIST_DECODENEXTITEM ((BURNERPLAYLIST_ERROR) + 0x111)
+#define BURNERPLAYLIST_DECODEITEM ((BURNERPLAYLIST_ERROR) + 0x112)
+
+#define BURNERPLAYLIST_NEWAUDIOFAILED ((BURNERPLAYLIST_ERROR) + 0x131)
+#define BURNERPLAYLIST_ADDITEMFAILED ((BURNERPLAYLIST_ERROR) + 0x132)
+#define BURNERPLAYLIST_ADDITEMSKIPPED ((BURNERPLAYLIST_ERROR) + 0x133)
+#define BURNERPLAYLIST_ITEMADDED ((BURNERPLAYLIST_ERROR) + 0x134)
+#define BURNERPLAYLIST_BEGINBURN ((BURNERPLAYLIST_ERROR) + 0x135)
+#define BURNERPLAYLIST_ENDBURN ((BURNERPLAYLIST_ERROR) + 0x136)
+#define BURNERPLAYLIST_BEGINBURNFAILED ((BURNERPLAYLIST_ERROR) + 0x137)
+#define BURNERPLAYLIST_ENDBURNFAILED ((BURNERPLAYLIST_ERROR) + 0x138)
+#define BURNERPLAYLIST_WRITEAUDIOFAILED ((BURNERPLAYLIST_ERROR) + 0x139)
+#define BURNERPLAYLIST_WRITELEADIN ((BURNERPLAYLIST_ERROR) + 0x13A)
+#define BURNERPLAYLIST_WRITEDATA ((BURNERPLAYLIST_ERROR) + 0x13B)
+#define BURNERPLAYLIST_WRITELEADOUT ((BURNERPLAYLIST_ERROR) + 0x13C)
+#define BURNERPLAYLIST_DISCOPEN ((BURNERPLAYLIST_ERROR) + 0x13D)
+#define BURNERPLAYLIST_DISCCLOSE ((BURNERPLAYLIST_ERROR) + 0x13E)
+#define BURNERPLAYLIST_WRITEITEMBEGIN ((BURNERPLAYLIST_ERROR) + 0x13F)
+#define BURNERPLAYLIST_WRITEITEMEND ((BURNERPLAYLIST_ERROR) + 0x140)
+#define BURNERPLAYLIST_BURNFAILED ((BURNERPLAYLIST_ERROR) + 0x141)
+//
+#define BURNERPLAYLIST_FILENOTLICENSED ((BURNERPLAYLIST_ERROR) + 0x150)
+
+// statuses
+#define BURNERPLAYLIST_LICENSINGFINISHED ((BURNERPLAYLIST_STATUS) + 0x001)
+#define BURNERPLAYLIST_LICENSINGSTARTING ((BURNERPLAYLIST_STATUS) + 0x002)
+#define BURNERPLAYLIST_LICENSINGPROGRESS ((BURNERPLAYLIST_STATUS) + 0x003)
+
+
+#define BURNERPLAYLIST_DECODEFINISHED ((BURNERPLAYLIST_STATUS) + 0x010)
+#define BURNERPLAYLIST_DECODESTARTING ((BURNERPLAYLIST_STATUS) + 0x011)
+#define BURNERPLAYLIST_DECODEPROGRESS ((BURNERPLAYLIST_STATUS) + 0x012)
+#define BURNERPLAYLIST_DECODECANCELING ((BURNERPLAYLIST_STATUS) + 0x013)
+
+#define BURNERPLAYLIST_BURNFINISHED ((BURNERPLAYLIST_STATUS) + 0x031)
+#define BURNERPLAYLIST_BURNSTARTING ((BURNERPLAYLIST_STATUS) + 0x032)
+#define BURNERPLAYLIST_BURNPROGRESS ((BURNERPLAYLIST_STATUS) + 0x033)
+#define BURNERPLAYLIST_BURNCANCELING ((BURNERPLAYLIST_STATUS) + 0x034)
+#define BURNERPLAYLIST_BURNFINISHING ((BURNERPLAYLIST_STATUS) + 0x035)
+
+
+// callback returns
+#define BURNERPLAYLIST_CONTINUE 0
+#define BURNERPLAYLIST_STOP 1
+
+
+typedef Vector<BurnerItem*> BurnerVector;
+
+typedef struct _BPLDECODEINFO
+{
+ BurnerItem *iInstance;
+ int iIndex;
+ DWORD iNotifyCode;
+ DWORD iErrorCode;
+ float percentCompleted;
+}BPLDECODEINFO;
+
+typedef struct _BPLRUNSTATUS
+{
+ DWORD sCurrent;
+ DWORD sTotal;
+ BurnerItem *iInstance;
+ int iIndex;
+ float percentCompleted;
+
+}BPLRUNSTATUS;
+
+typedef DWORD (WINAPI *BURNERPLAYLISTCALLBACK)(void *sender, void *userparam, DWORD notifyCode, DWORD errorCode, ULONG_PTR param);
+
+
+class BurnerPlaylist : private ifc_playlistloadercallback, BurnerVector, BurnManagerCallback
+{
+public:
+ BURNLIB_API BurnerPlaylist(void);
+ BURNLIB_API ~BurnerPlaylist(void);
+ BURNLIB_API HRESULT Load(const wchar_t *filename);
+ BURNLIB_API HRESULT CheckLicense(BURNERPLAYLISTCALLBACK notifyCB, void *userparam);
+ BURNLIB_API HRESULT Decode(void* hFile, BURNERPLAYLISTCALLBACK notifyCB, void *userparam, BOOL block);
+ BURNLIB_API HRESULT Burn(obj_primo *primoSDK, DWORD drive, DWORD maxspeed, DWORD burnFlags, void* hFile,
+ BURNERPLAYLISTCALLBACK notifyCB, void *userparam, BOOL block);
+ BURNLIB_API DWORD AddCompilationToCDDB(void);
+ BURNLIB_API size_t GetCount(void) { return size(); }
+ BURNLIB_API DWORD GetTotalLengthMS(void) { return length; }
+ BURNLIB_API BurnerItem* &operator[](size_t index) { return BurnerVector::at(index); }
+ BURNLIB_API BurnerItem* &at(size_t index) { return BurnerVector::at(index); }
+ BURNLIB_API DWORD GetTotalSectors(void);
+ BURNLIB_API BOOL SetEjectWhenDone(BOOL eject) { BOOL tmp = ejectDone; ejectDone = eject; return tmp; }
+ BURNLIB_API DWORD GetStatus(DWORD *retCode); // if retCode not NULL - can return completed percentage or error code
+ // state based calls
+ BURNLIB_API size_t GetStateCount(DWORD state, DWORD code);
+ BURNLIB_API DWORD GetStateLengthMS(DWORD state, DWORD code);
+ BURNLIB_API DWORD GetStateSectors(DWORD state, DWORD code);
+
+protected:
+ static DWORD WINAPI DecodeWorker(void* param);
+ static DWORD WINAPI BurnerWorker(void* param);
+ void OnFile(const wchar_t *filename, const wchar_t *title, int lengthInMS, ifc_plentryinfo *info);
+ static DWORD WINAPI OnItemDecode(void* sender, void *param, DWORD notifyCode, DWORD errorCode);
+ DWORD OnNotify(DWORD notifyCode, DWORD errorCode, ULONG_PTR param);
+ void OnLicenseCallback(size_t numFiles, WRESULT *results);
+ RECVS_DISPATCH;
+
+protected:
+ unsigned long length;
+ wchar_t tmpfullname;
+ obj_primo *primoSDK;
+ DWORD drive;
+ BURNERPLAYLISTCALLBACK notifyCB;
+ void *userparam;
+ HANDLE hThread;
+ HANDLE hFile;
+ BPLDECODEINFO *activeDecode;
+ float percentStep;
+ DWORD maxspeed;
+ DWORD burnFlags;
+ DWORD statusCode;
+ DWORD errorCode;
+ HANDLE evntCancel;
+ BOOL ejectDone;
+ BurnManager manager;
+};
+
+#endif //NULLSOFT_BurnerPlaylist_HEADER \ No newline at end of file
diff --git a/Src/burnlib/primosdk.h b/Src/burnlib/primosdk.h
new file mode 100644
index 00000000..4ccc6654
--- /dev/null
+++ b/Src/burnlib/primosdk.h
@@ -0,0 +1,53 @@
+#ifndef NULLSOFT_PRIMOSDK_INTEGRATION_HEADER
+#define NULLSOFT_PRIMOSDK_INTEGRATION_HEADER
+
+#include "./main.h"
+// PrimoSDK wrapper
+
+#define PRIMOSDK_OK 0x0000 - declared in PRIMODSK.H
+
+#define PRIMOSDK_ERROR 0x0001
+#define PRIMOSDK_ALREADYLOADED 0x1000
+#define PRIMOSDK_LOAD_DLLFAILED 0x1001
+#define PRIMOSDK_LOAD_FUNCFAILED 0x1002
+#define PRIMOSDK_NOTLOADED 0x1003
+#define PRIMOSDK_FUNCNOTLOADED 0x1004
+#define PRIMOSDK_NULLHANDLE 0x1005
+#define PRIMOSDK_INTERR 0x1006
+#define PRIMOSDK_UNLOCK 0
+#define PRIMOSDK_WRITE 0
+#include "../primo/obj_primo.h"
+
+
+// MAXDWORD - for not care
+typedef struct _WAMEDIUMINFO
+{
+ DWORD medium;
+ DWORD mediumType;
+ DWORD tracks;
+ DWORD mediumFormat;
+ DWORD freeSectors;
+ DWORD usedSectors;
+ DWORD protectedDVD;
+ DWORD erasable;
+ DWORD recordable;
+ DWORD isCD;
+ DWORD isDCD;
+ DWORD isDVD;
+ DWORD isDLDVD;
+}WAMEDIUMINFO;
+
+
+typedef struct _WABURNSTRUCT
+{
+ obj_primo *primoSDK; // sdk object
+ DWORD drive; // working drive (filled by BeginBurn)
+ PBYTE blocker; // current blocker name (filled by BeginBurn)
+ int eject; // if set to TRUE - endBurn will eject disc otherwise just stop motor
+} WABURNSTRUCT; // passed to the BeginBurn or EndBurn functions
+
+BURNLIB_API DWORD GetMediumInfo(obj_primo *primoSDK, DWORD *drive, WAMEDIUMINFO *info);
+BURNLIB_API DWORD BeginBurn(obj_primo *primoSDK, DWORD drive, WABURNSTRUCT *burnstruct);
+BURNLIB_API DWORD EndBurn(WABURNSTRUCT *burnstruct);
+
+#endif // NULLSOFT_PRIMOSDK_INTEGRATION_HEADER \ No newline at end of file
diff --git a/Src/burnlib/resdll/resdll.vcproj b/Src/burnlib/resdll/resdll.vcproj
new file mode 100644
index 00000000..5a6ea795
--- /dev/null
+++ b/Src/burnlib/resdll/resdll.vcproj
@@ -0,0 +1,225 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="burnlibres"
+ ProjectGUID="{8FBD5E01-B920-44D8-9687-88AE0C3CA833}"
+ RootNamespace="burnlibres"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;RESDLL_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="true"
+ ShowProgress="0"
+ OutputFile="$(ProgramFiles)\Winamp\burnlib.dll"
+ LinkIncremental="1"
+ IgnoreAllDefaultLibraries="true"
+ IgnoreDefaultLibraryNames="msvcrtd.lib"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/resdll.pdb"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ResourceOnlyDLL="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="../lib/burnlibres.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ WholeProgramOptimization="0"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;RESDLL_EXPORTS"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="true"
+ ShowProgress="0"
+ OutputFile="$(ProgramFiles)\Winamp\burnlib.dll"
+ LinkIncremental="1"
+ GenerateManifest="false"
+ IgnoreAllDefaultLibraries="true"
+ GenerateDebugInformation="false"
+ ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ResourceOnlyDLL="true"
+ RandomizedBaseAddress="1"
+ ImportLibrary="../lib/burnlibres.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\resource.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ <File
+ RelativePath="..\burnlib.rc"
+ >
+ </File>
+ <File
+ RelativePath="..\resources\disc1.bmp"
+ >
+ </File>
+ <File
+ RelativePath="..\resources\drive1.bmp"
+ >
+ </File>
+ <File
+ RelativePath="..\resources\testmode.bmp"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/Src/burnlib/resource.h b/Src/burnlib/resource.h
new file mode 100644
index 00000000..6206197c
--- /dev/null
+++ b/Src/burnlib/resource.h
@@ -0,0 +1,650 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by burnlib.rc
+//
+#define IDD_DLG_UNITNOTREADY 9
+#define IDD_DLG_WRONGMEDIUM 102
+#define IDD_DLG_ERASEMEDIUMSTATUS 103
+#define IDD_DLG_ERASEMEDIUMPREPARE 104
+#define IDD_DLG_UPDATING 105
+#define IDB_DRIVE1 106
+#define IDB_DISC1 107
+#define IDD_DLG_BURNER 108
+#define IDB_TESTMODE 109
+#define IDS_MEDIUM_BDR 110
+#define IDS_COLUMN_INDEX 111
+#define IDS_COLUMN_TITLE 112
+#define IDS_COLUMN_DURATION 113
+#define IDD_DLG 113
+#define IDD_DLG_COMPILATION 113
+#define IDS_COLUMN_STATUS 114
+#define IDS_COLUMN_FILE 115
+#define IDS_OK 116
+#define IDS_CANCEL 117
+#define IDS_STOP 118
+#define IDS_CLOSE 119
+#define IDS_UNKNOWN 120
+#define IDS_YES 121
+#define IDS_NO 122
+#define IDS_MEDIUM_CD 123
+#define IDS_MEDIUM_CDR 124
+#define IDS_MEDIUM_CDRW 125
+#define IDS_MEDIUM_DVD 126
+#define IDS_MEDIUM_DVDR 127
+#define IDS_MEDIUM_DVDRW 128
+#define IDS_MEDIUM_DVDPR 129
+#define IDS_MEDIUM_DVDPRW 130
+#define IDS_MEDIUM_DVDRAM 131
+#define IDS_MEDIUM_DDCD 132
+#define IDS_MEDIUM_DDCDR 133
+#define IDS_MEDIUM_DDCDRW 134
+#define IDS_MEDIUM_DVDPR9 135
+#define IDS_MEDIUM_DVDR9 136
+#define IDS_MEDIUM_BDRE 137
+#define IDS_MEDIUMTYPE_SILVER 138
+#define IDS_MEDIUMTYPE_COMPILATIONGOLD 139
+#define IDS_MEDIUMTYPE_OTHERGOLD 140
+#define IDS_MEDIUMTYPE_BLANK 141
+#define IDS_MEDIUMFORMAT_B1 142
+#define IDS_MEDIUMFORMAT_D1 143
+#define IDS_MEDIUMFORMAT_D2 144
+#define IDS_MEDIUMFORMAT_D3 145
+#define IDS_MEDIUMFORMAT_D4 146
+#define IDS_MEDIUMFORMAT_D5 147
+#define IDS_MEDIUMFORMAT_D6 148
+#define IDS_MEDIUMFORMAT_D7 149
+#define IDS_MEDIUMFORMAT_D8 150
+#define IDS_MEDIUMFORMAT_D9 151
+#define IDS_MEDIUMFORMAT_A1 152
+#define IDS_MEDIUMFORMAT_A2 153
+#define IDS_MEDIUMFORMAT_A3 154
+#define IDS_MEDIUMFORMAT_A4 155
+#define IDS_MEDIUMFORMAT_A5 156
+#define IDS_MEDIUMFORMAT_M1 157
+#define IDS_MEDIUMFORMAT_M2 158
+#define IDS_MEDIUMFORMAT_M3 159
+#define IDS_MEDIUMFORMAT_M4 160
+#define IDS_MEDIUMFORMAT_M5 161
+#define IDS_MEDIUMFORMAT_M6 162
+#define IDS_MEDIUMFORMAT_F1 163
+#define IDS_MEDIUMFORMAT_F2 164
+#define IDS_MEDIUMFORMAT_F3 165
+#define IDS_MEDIUMFORMAT_F4 166
+#define IDS_MEDIUMFORMAT_F5 167
+#define IDS_MEDIUMFORMAT_F8 168
+#define IDS_MEDIUMFORMAT_FA 169
+#define IDS_MEDIUMFORMAT_GENERICCD 170
+#define IDS_BUSSTYPE_ATAPI 171
+#define IDS_BUSSTYPE_SCSI 172
+#define IDS_BUSSTYPE_1394 173
+#define IDS_BUSSTYPE_USB 174
+#define IDS_BUSSTYPE_USB2 175
+#define IDS_TRACKTYPE_AUDIO 176
+#define IDS_TRACKTYPE_TRACK1 177
+#define IDS_TRACKTYPE_TRACK2 178
+#define IDS_PRIMOCODE_OK 179
+#define IDS_PRIMOCODE_CMDSEQUENCE 180
+#define IDS_PRIMOCODE_NOASPI 181
+#define IDS_PRIMOCODE_INTERR 182
+#define IDS_PRIMOCODE_BADPARAM 183
+#define IDS_PRIMOCODE_ALREADYEXIST 184
+#define IDS_PRIMOCODE_NOTREADABLE 185
+#define IDS_PRIMOCODE_NOSPACE 186
+#define IDS_PRIMOCODE_INVALIDMEDIUM 187
+#define IDS_PRIMOCODE_RUNNING 188
+#define IDS_PRIMOCODE_BUR 189
+#define IDS_PRIMOCODE_SCSIERROR 190
+#define IDS_PRIMOCODE_UNITERROR 191
+#define IDS_PRIMOCODE_NOTREADY 192
+#define IDS_PRIMOCODE_INVALIDSOURCE 193
+#define IDS_PRIMOCODE_INCOMPATIBLE 194
+#define IDS_PRIMOCODE_FILEERROR 195
+#define IDS_PRIMOCODE_ITSADEMO 196
+#define IDS_PRIMOCODE_USERABORT 197
+#define IDS_PRIMOCODE_BADHANDLE 198
+#define IDS_PRIMOCODE_BADUNIT 199
+#define IDS_PRIMOCODE_ERRORLOADING 200
+#define IDS_PRIMOCODE_NOAINCONTROL 201
+#define IDS_PRIMOCODE_READERROR 202
+#define IDS_PRIMOCODE_WRITEERROR 203
+#define IDS_PRIMOCODE_TMPOVERFLOW 204
+#define IDS_PRIMOCODE_DVDSTRUCTERROR 205
+#define IDS_PRIMOCODE_FILETOOLARGE 206
+#define IDS_PRIMOCODE_CACHEFULL 207
+#define IDS_PRIMOCODE_FEATURE_NOT_SUPPORTED 208
+#define IDS_PRIMOCODE_FEATURE_DISABLED 209
+#define IDS_PRIMOCODE_CALLBACK_ERROR 210
+#define IDS_PRIMOCODE_PROTECTEDWMA 211
+#define IDS_DRIVEERRORCODE_000000 212
+#define IDS_DRIVEERRORCODE_000001 213
+#define IDS_DRIVEERRORCODE_000002 214
+#define IDS_DRIVEERRORCODE_000003 215
+#define IDS_DRIVEERRORCODE_000004 216
+#define IDS_DRIVEERRORCODE_000005 217
+#define IDS_DRIVEERRORCODE_000011 218
+#define IDS_DRIVEERRORCODE_000012 219
+#define IDS_DRIVEERRORCODE_000013 220
+#define IDS_DRIVEERRORCODE_000014 221
+#define IDS_DRIVEERRORCODE_000015 222
+#define IDS_DRIVEERRORCODE_000016 223
+#define IDS_DRIVEERRORCODE_010B00 224
+#define IDS_DRIVEERRORCODE_010B01 225
+#define IDS_DRIVEERRORCODE_010B02 226
+#define IDS_DRIVEERRORCODE_010C0A 227
+#define IDS_DRIVEERRORCODE_011700 228
+#define IDS_DRIVEERRORCODE_011701 229
+#define IDS_DRIVEERRORCODE_011702 230
+#define IDS_DRIVEERRORCODE_011703 231
+#define IDS_DRIVEERRORCODE_011704 232
+#define IDS_DRIVEERRORCODE_011705 233
+#define IDS_DRIVEERRORCODE_011706 234
+#define IDS_DRIVEERRORCODE_011707 235
+#define IDS_DRIVEERRORCODE_011708 236
+#define IDS_DRIVEERRORCODE_011709 237
+#define IDS_DRIVEERRORCODE_011800 238
+#define IDS_DRIVEERRORCODE_011801 239
+#define IDS_DRIVEERRORCODE_011802 240
+#define IDS_DRIVEERRORCODE_011803 241
+#define IDS_DRIVEERRORCODE_011804 242
+#define IDS_DRIVEERRORCODE_011805 243
+#define IDS_DRIVEERRORCODE_011806 244
+#define IDS_DRIVEERRORCODE_011807 245
+#define IDS_DRIVEERRORCODE_011808 246
+#define IDS_DRIVEERRORCODE_011E00 247
+#define IDS_DRIVEERRORCODE_013700 248
+#define IDS_DRIVEERRORCODE_015D00 249
+#define IDS_DRIVEERRORCODE_015D01 250
+#define IDS_DRIVEERRORCODE_015DFF 251
+#define IDS_DRIVEERRORCODE_016A00 252
+#define IDS_DRIVEERRORCODE_017301 253
+#define IDS_DRIVEERRORCODE_017306 254
+#define IDS_DRIVEERRORCODE_020400 255
+#define IDS_DRIVEERRORCODE_020401 256
+#define IDS_DRIVEERRORCODE_020402 257
+#define IDS_DRIVEERRORCODE_020403 258
+#define IDS_DRIVEERRORCODE_020404 259
+#define IDS_DRIVEERRORCODE_020405 260
+#define IDS_DRIVEERRORCODE_020406 261
+#define IDS_DRIVEERRORCODE_020407 262
+#define IDS_DRIVEERRORCODE_020408 263
+#define IDS_DRIVEERRORCODE_020500 264
+#define IDS_DRIVEERRORCODE_020600 265
+#define IDS_DRIVEERRORCODE_023000 266
+#define IDS_DRIVEERRORCODE_023001 267
+#define IDS_DRIVEERRORCODE_023002 268
+#define IDS_DRIVEERRORCODE_023003 269
+#define IDS_DRIVEERRORCODE_023004 270
+#define IDS_DRIVEERRORCODE_023005 271
+#define IDS_DRIVEERRORCODE_023007 272
+#define IDS_DRIVEERRORCODE_023502 273
+#define IDS_DRIVEERRORCODE_023A00 274
+#define IDS_DRIVEERRORCODE_023A01 275
+#define IDS_DRIVEERRORCODE_023A02 276
+#define IDS_DRIVEERRORCODE_023E00 277
+#define IDS_DRIVEERRORCODE_025300 278
+#define IDS_DRIVEERRORCODE_025302 279
+#define IDS_DRIVEERRORCODE_025700 280
+#define IDS_DRIVEERRORCODE_026800 281
+#define IDS_DRIVEERRORCODE_030014 282
+#define IDS_DRIVEERRORCODE_030200 283
+#define IDS_DRIVEERRORCODE_030280 284
+#define IDS_DRIVEERRORCODE_030281 285
+#define IDS_DRIVEERRORCODE_030282 286
+#define IDS_DRIVEERRORCODE_030283 287
+#define IDS_DRIVEERRORCODE_030300 288
+#define IDS_DRIVEERRORCODE_030301 289
+#define IDS_DRIVEERRORCODE_030302 290
+#define IDS_DRIVEERRORCODE_030600 291
+#define IDS_DRIVEERRORCODE_030C00 292
+#define IDS_DRIVEERRORCODE_030C01 293
+#define IDS_DRIVEERRORCODE_030C02 294
+#define IDS_DRIVEERRORCODE_030C03 295
+#define IDS_DRIVEERRORCODE_030C04 296
+#define IDS_DRIVEERRORCODE_030C05 297
+#define IDS_DRIVEERRORCODE_030C06 298
+#define IDS_DRIVEERRORCODE_030C07 299
+#define IDS_DRIVEERRORCODE_030C08 300
+#define IDS_DRIVEERRORCODE_030C09 301
+#define IDS_DRIVEERRORCODE_030C0A 302
+#define IDS_DRIVEERRORCODE_031000 303
+#define IDS_DRIVEERRORCODE_031100 304
+#define IDS_DRIVEERRORCODE_031101 305
+#define IDS_DRIVEERRORCODE_031102 306
+#define IDS_DRIVEERRORCODE_031103 307
+#define IDS_DRIVEERRORCODE_031104 308
+#define IDS_DRIVEERRORCODE_031105 309
+#define IDS_DRIVEERRORCODE_031106 310
+#define IDS_DRIVEERRORCODE_031107 311
+#define IDS_DRIVEERRORCODE_031108 312
+#define IDS_DRIVEERRORCODE_031109 313
+#define IDS_DRIVEERRORCODE_03110A 314
+#define IDS_DRIVEERRORCODE_03110B 315
+#define IDS_DRIVEERRORCODE_03110C 316
+#define IDS_DRIVEERRORCODE_03110D 317
+#define IDS_DRIVEERRORCODE_03110E 318
+#define IDS_DRIVEERRORCODE_03110F 319
+#define IDS_DRIVEERRORCODE_031110 320
+#define IDS_DRIVEERRORCODE_031200 321
+#define IDS_DRIVEERRORCODE_031300 322
+#define IDS_DRIVEERRORCODE_031400 323
+#define IDS_DRIVEERRORCODE_031401 324
+#define IDS_DRIVEERRORCODE_031402 325
+#define IDS_DRIVEERRORCODE_031403 326
+#define IDS_DRIVEERRORCODE_031404 327
+#define IDS_DRIVEERRORCODE_031405 328
+#define IDS_DRIVEERRORCODE_031406 329
+#define IDS_DRIVEERRORCODE_031500 330
+#define IDS_DRIVEERRORCODE_031501 331
+#define IDS_DRIVEERRORCODE_031502 332
+#define IDS_DRIVEERRORCODE_031600 333
+#define IDS_DRIVEERRORCODE_031601 334
+#define IDS_DRIVEERRORCODE_031602 335
+#define IDS_DRIVEERRORCODE_031603 336
+#define IDS_DRIVEERRORCODE_031604 337
+#define IDS_DRIVEERRORCODE_031900 338
+#define IDS_DRIVEERRORCODE_031901 339
+#define IDS_DRIVEERRORCODE_031902 340
+#define IDS_DRIVEERRORCODE_031903 341
+#define IDS_DRIVEERRORCODE_031F00 342
+#define IDS_DRIVEERRORCODE_032D00 343
+#define IDS_DRIVEERRORCODE_033000 344
+#define IDS_DRIVEERRORCODE_033100 345
+#define IDS_DRIVEERRORCODE_033101 346
+#define IDS_DRIVEERRORCODE_033102 347
+#define IDS_DRIVEERRORCODE_033200 348
+#define IDS_DRIVEERRORCODE_033201 349
+#define IDS_DRIVEERRORCODE_033300 350
+#define IDS_DRIVEERRORCODE_033600 351
+#define IDS_DRIVEERRORCODE_033B00 352
+#define IDS_DRIVEERRORCODE_033B01 353
+#define IDS_DRIVEERRORCODE_033B02 354
+#define IDS_DRIVEERRORCODE_033B03 355
+#define IDS_DRIVEERRORCODE_033B06 356
+#define IDS_DRIVEERRORCODE_033B07 357
+#define IDS_DRIVEERRORCODE_033B08 358
+#define IDS_DRIVEERRORCODE_033B09 359
+#define IDS_DRIVEERRORCODE_033B0A 360
+#define IDS_DRIVEERRORCODE_033B0B 361
+#define IDS_DRIVEERRORCODE_033B0C 362
+#define IDS_DRIVEERRORCODE_035100 363
+#define IDS_DRIVEERRORCODE_035200 364
+#define IDS_DRIVEERRORCODE_035700 365
+#define IDS_DRIVEERRORCODE_035C02 366
+#define IDS_DRIVEERRORCODE_036100 367
+#define IDS_DRIVEERRORCODE_036101 368
+#define IDS_DRIVEERRORCODE_036102 369
+#define IDS_DRIVEERRORCODE_036C00 370
+#define IDS_DRIVEERRORCODE_036D00 371
+#define IDS_DRIVEERRORCODE_0370NN 372
+#define IDS_DRIVEERRORCODE_037100 373
+#define IDS_DRIVEERRORCODE_037200 374
+#define IDS_DRIVEERRORCODE_037201 375
+#define IDS_DRIVEERRORCODE_037202 376
+#define IDS_DRIVEERRORCODE_037300 377
+#define IDS_DRIVEERRORCODE_037302 378
+#define IDS_DRIVEERRORCODE_037303 379
+#define IDS_DRIVEERRORCODE_037304 380
+#define IDS_DRIVEERRORCODE_037305 381
+#define IDS_DRIVEERRORCODE_040017 382
+#define IDS_DRIVEERRORCODE_040100 383
+#define IDS_DRIVEERRORCODE_040500 384
+#define IDS_DRIVEERRORCODE_040800 385
+#define IDS_DRIVEERRORCODE_040801 386
+#define IDS_DRIVEERRORCODE_040802 387
+#define IDS_DRIVEERRORCODE_040803 388
+#define IDS_DRIVEERRORCODE_040900 389
+#define IDS_DRIVEERRORCODE_040901 390
+#define IDS_DRIVEERRORCODE_040902 391
+#define IDS_DRIVEERRORCODE_040903 392
+#define IDS_DRIVEERRORCODE_040904 393
+#define IDS_DRIVEERRORCODE_041B00 394
+#define IDS_DRIVEERRORCODE_041C00 395
+#define IDS_DRIVEERRORCODE_041C01 396
+#define IDS_DRIVEERRORCODE_041C02 397
+#define IDS_DRIVEERRORCODE_043400 398
+#define IDS_DRIVEERRORCODE_043500 399
+#define IDS_DRIVEERRORCODE_043503 400
+#define IDS_DRIVEERRORCODE_043B04 401
+#define IDS_DRIVEERRORCODE_043B05 402
+#define IDS_DRIVEERRORCODE_043B16 403
+#define IDS_DRIVEERRORCODE_043E01 404
+#define IDS_DRIVEERRORCODE_043E02 405
+#define IDS_DRIVEERRORCODE_044000 406
+#define IDS_DRIVEERRORCODE_0440NN 407
+#define IDS_DRIVEERRORCODE_044100 408
+#define IDS_DRIVEERRORCODE_044200 409
+#define IDS_DRIVEERRORCODE_044400 410
+#define IDS_DRIVEERRORCODE_044600 411
+#define IDS_DRIVEERRORCODE_044700 412
+#define IDS_DRIVEERRORCODE_044A00 413
+#define IDS_DRIVEERRORCODE_044B00 414
+#define IDS_DRIVEERRORCODE_044C00 415
+#define IDS_DRIVEERRORCODE_045300 416
+#define IDS_DRIVEERRORCODE_045400 417
+#define IDS_DRIVEERRORCODE_046000 418
+#define IDS_DRIVEERRORCODE_046200 419
+#define IDS_DRIVEERRORCODE_046500 420
+#define IDS_DRIVEERRORCODE_046600 421
+#define IDS_DRIVEERRORCODE_046601 422
+#define IDS_DRIVEERRORCODE_046602 423
+#define IDS_DRIVEERRORCODE_046603 424
+#define IDS_DRIVEERRORCODE_046700 425
+#define IDS_DRIVEERRORCODE_046701 426
+#define IDS_DRIVEERRORCODE_046702 427
+#define IDS_DRIVEERRORCODE_046703 428
+#define IDS_DRIVEERRORCODE_046704 429
+#define IDS_DRIVEERRORCODE_046705 430
+#define IDS_DRIVEERRORCODE_046706 431
+#define IDS_DRIVEERRORCODE_046707 432
+#define IDS_DRIVEERRORCODE_046901 433
+#define IDS_DRIVEERRORCODE_046902 434
+#define IDS_DRIVEERRORCODE_046E00 435
+#define IDS_DRIVEERRORCODE_04B600 436
+#define IDS_DRIVEERRORCODE_050011 437
+#define IDS_DRIVEERRORCODE_050700 438
+#define IDS_DRIVEERRORCODE_051A00 439
+#define IDS_DRIVEERRORCODE_052000 440
+#define IDS_DRIVEERRORCODE_052100 441
+#define IDS_DRIVEERRORCODE_052101 442
+#define IDS_DRIVEERRORCODE_052102 443
+#define IDS_DRIVEERRORCODE_052200 444
+#define IDS_DRIVEERRORCODE_052400 445
+#define IDS_DRIVEERRORCODE_052500 446
+#define IDS_DRIVEERRORCODE_052600 447
+#define IDS_DRIVEERRORCODE_052601 448
+#define IDS_DRIVEERRORCODE_052602 449
+#define IDS_DRIVEERRORCODE_052603 450
+#define IDS_DRIVEERRORCODE_052604 451
+#define IDS_DRIVEERRORCODE_052700 452
+#define IDS_DRIVEERRORCODE_052701 453
+#define IDS_DRIVEERRORCODE_052702 454
+#define IDS_DRIVEERRORCODE_052703 455
+#define IDS_DRIVEERRORCODE_052704 456
+#define IDS_DRIVEERRORCODE_052705 457
+#define IDS_DRIVEERRORCODE_052B00 458
+#define IDS_DRIVEERRORCODE_052C00 459
+#define IDS_DRIVEERRORCODE_052C01 460
+#define IDS_DRIVEERRORCODE_052C02 461
+#define IDS_DRIVEERRORCODE_052C03 462
+#define IDS_DRIVEERRORCODE_052C04 463
+#define IDS_DRIVEERRORCODE_053000 464
+#define IDS_DRIVEERRORCODE_053002 465
+#define IDS_DRIVEERRORCODE_053004 466
+#define IDS_DRIVEERRORCODE_053005 467
+#define IDS_DRIVEERRORCODE_053006 468
+#define IDS_DRIVEERRORCODE_053008 469
+#define IDS_DRIVEERRORCODE_053009 470
+#define IDS_DRIVEERRORCODE_053501 471
+#define IDS_DRIVEERRORCODE_053504 472
+#define IDS_DRIVEERRORCODE_053800 473
+#define IDS_DRIVEERRORCODE_053900 474
+#define IDS_DRIVEERRORCODE_053D00 475
+#define IDS_DRIVEERRORCODE_054300 476
+#define IDS_DRIVEERRORCODE_055302 477
+#define IDS_DRIVEERRORCODE_055500 478
+#define IDS_DRIVEERRORCODE_056300 479
+#define IDS_DRIVEERRORCODE_056301 480
+#define IDS_DRIVEERRORCODE_056400 481
+#define IDS_DRIVEERRORCODE_056401 482
+#define IDS_DRIVEERRORCODE_056F00 483
+#define IDS_DRIVEERRORCODE_056F01 484
+#define IDS_DRIVEERRORCODE_056F02 485
+#define IDS_DRIVEERRORCODE_056F03 486
+#define IDS_DRIVEERRORCODE_056F04 487
+#define IDS_DRIVEERRORCODE_056F05 488
+#define IDS_DRIVEERRORCODE_057203 489
+#define IDS_DRIVEERRORCODE_057204 490
+#define IDS_DRIVEERRORCODE_057205 491
+#define IDS_DRIVEERRORCODE_058100 492
+#define IDS_DRIVEERRORCODE_058500 493
+#define IDS_DRIVEERRORCODE_060A00 494
+#define IDS_DRIVEERRORCODE_062800 495
+#define IDS_DRIVEERRORCODE_062801 496
+#define IDS_DRIVEERRORCODE_062900 497
+#define IDS_DRIVEERRORCODE_062901 498
+#define IDS_DRIVEERRORCODE_062902 499
+#define IDS_DRIVEERRORCODE_062903 500
+#define IDS_DRIVEERRORCODE_062904 501
+#define IDS_DRIVEERRORCODE_062A00 502
+#define IDS_DRIVEERRORCODE_062A01 503
+#define IDS_DRIVEERRORCODE_062A02 504
+#define IDS_DRIVEERRORCODE_062A03 505
+#define IDS_DRIVEERRORCODE_062E00 506
+#define IDS_DRIVEERRORCODE_062F00 507
+#define IDS_DRIVEERRORCODE_063B0D 508
+#define IDS_DRIVEERRORCODE_063B0E 509
+#define IDS_DRIVEERRORCODE_063B0F 510
+#define IDS_DRIVEERRORCODE_063B11 511
+#define IDS_DRIVEERRORCODE_063B12 512
+#define IDS_DRIVEERRORCODE_063B13 513
+#define IDS_DRIVEERRORCODE_063B14 514
+#define IDS_DRIVEERRORCODE_063B15 515
+#define IDS_DRIVEERRORCODE_063F00 516
+#define IDS_DRIVEERRORCODE_063F01 517
+#define IDS_DRIVEERRORCODE_063F02 518
+#define IDS_DRIVEERRORCODE_063F03 519
+#define IDS_DRIVEERRORCODE_065501 520
+#define IDS_DRIVEERRORCODE_065A00 521
+#define IDS_DRIVEERRORCODE_065A01 522
+#define IDS_DRIVEERRORCODE_065A02 523
+#define IDS_DRIVEERRORCODE_065A03 524
+#define IDS_DRIVEERRORCODE_065B00 525
+#define IDS_DRIVEERRORCODE_065B01 526
+#define IDS_DRIVEERRORCODE_065B02 527
+#define IDS_DRIVEERRORCODE_065B03 528
+#define IDS_DRIVEERRORCODE_065C00 529
+#define IDS_DRIVEERRORCODE_065C01 530
+#define IDS_DRIVEERRORCODE_065E00 531
+#define IDS_DRIVEERRORCODE_065E01 532
+#define IDS_DRIVEERRORCODE_065E02 533
+#define IDS_DRIVEERRORCODE_065E03 534
+#define IDS_DRIVEERRORCODE_065E04 535
+#define IDS_DRIVEERRORCODE_066A00 536
+#define IDS_DRIVEERRORCODE_066B00 537
+#define IDS_DRIVEERRORCODE_066B01 538
+#define IDS_DRIVEERRORCODE_066B02 539
+#define IDS_DRIVEERRORCODE_072700 540
+#define IDS_DRIVEERRORCODE_072701 541
+#define IDS_DRIVEERRORCODE_072702 542
+#define IDS_DRIVEERRORCODE_072703 543
+#define IDS_DRIVEERRORCODE_072704 544
+#define IDS_DRIVEERRORCODE_072705 545
+#define IDS_DRIVEERRORCODE_082102 546
+#define IDS_DRIVEERRORCODE_098000 547
+#define IDS_DRIVEERRORCODE_098001 548
+#define IDS_DRIVEERRORCODE_098005 549
+#define IDS_DRIVEERRORCODE_098006 550
+#define IDS_DRIVEERRORCODE_098007 551
+#define IDS_DRIVEERRORCODE_09800A 552
+#define IDS_DRIVEERRORCODE_09800B 553
+#define IDS_DRIVEERRORCODE_09800C 554
+#define IDS_DRIVEERRORCODE_0B0006 555
+#define IDS_DRIVEERRORCODE_0B1111 556
+#define IDS_DRIVEERRORCODE_0B4300 557
+#define IDS_DRIVEERRORCODE_0B4500 558
+#define IDS_DRIVEERRORCODE_0B4800 559
+#define IDS_DRIVEERRORCODE_0B4900 560
+#define IDS_DRIVEERRORCODE_0B4DNN 561
+#define IDS_DRIVEERRORCODE_0B4E00 562
+#define IDS_DRIVEERRORCODE_0BB900 563
+#define IDS_DRIVEERRORCODE_0E1D00 564
+#define IDS_DRIVEERRORCODE_0X0D00 565
+#define IDS_DRIVEERRORCODE_0X0E00 566
+#define IDS_DRIVEERRORCODE_0X0F00 567
+#define IDS_DRIVEERRORCODE_0X2300 568
+#define IDS_DRIVEERRORCODE_0X4F00 569
+#define IDS_DRIVEERRORCODE_0X5000 570
+#define IDS_DRIVEERRORCODE_0X5001 571
+#define IDS_DRIVEERRORCODE_0X5002 572
+#define IDS_DRIVEERRORCODE_0X5301 573
+#define IDS_DRIVEERRORCODE_0X5400 574
+#define IDS_DRIVEERRORCODE_0X5501 575
+#define IDS_DRIVEERRORCODE_0X5600 576
+#define IDS_DRIVEERRORCODE_0X5800 577
+#define IDS_DRIVEERRORCODE_0X5900 578
+#define IDS_DRIVEERRORCODE_0X5F00 579
+#define IDS_DRIVEERRORCODE_0X80XX 580
+#define IDS_UNITNOTREADY 581
+#define IDS_WAITINGFORDRIVE 582
+#define IDS_CONFIRMATION 583
+#define IDS_MB_CANCELOPERATION 584
+#define IDS_UPDATINGDATA 585
+#define IDS_UNABLEGETDISCINFO 586
+#define IDS_READINGDISCINFO 587
+#define IDS_DISCERASABLE 588
+#define IDS_DISCNONERASABLE 589
+#define IDS_DISCINFOFORMAT 590
+#define IDS_DISCSIZEFORMAT 591
+#define IDS_WRONGMEDIUM 592
+#define IDS_SELECTERASEMETHOD 593
+#define IDS_QUICKERASE 594
+#define IDS_COMPLETEERASE 595
+#define IDS_ERASEREQDISC 596
+#define IDS_INITIALIZING 597
+#define IDS_FINISHING 598
+#define IDS_COMPLETING 599
+#define IDS_STARTING 600
+#define IDS_CANCELING 601
+#define IDS_ABORTING 602
+#define IDS_FINISHED 603
+#define IDS_ABORTED 604
+#define IDS_ERROR 605
+#define IDS_COMPLETED 606
+#define IDS_READY 607
+#define IDS_CANCELED 608
+#define IDS_ERASING 609
+#define IDS_UNKNOWNERROR 610
+#define IDS_DRIVENOTREADY 611
+#define IDS_MEDIUMERASEFAILED 612
+#define IDS_UNABLEINITERASE 613
+#define IDS_UNABLEFINERASE 614
+#define IDS_ALREADYERASING 615
+#define IDS_PRIMOINITFAILED 616
+#define IDS_BURNINGCDDA 617
+#define IDS_ERROROCCURED 618
+#define IDS_TMPCREATEFAILED 619
+#define IDS_BURNINGABORTEDBYUSER 620
+#define IDS_SHOWLESS 621
+#define IDS_SHOWMORE 622
+#define IDS_PREPARING 623
+#define IDS_BURNING 624
+#define IDS_CHECKINGDISC 625
+#define IDS_BURNREQDISC 626
+#define IDS_SPEEDBEST 627
+#define IDS_SPEEDMAX 628
+#define IDS_SPEEDMIN 629
+#define IDS_SPEEDMED 630
+#define IDS_SPEED 631
+#define IDS_AT 632
+#define IDS_BURNINGCANCELED 633
+#define IDS_REASON 634
+#define IDS_CURRENTOPERATION 635
+#define IDS_LICENSEFAILED 636
+#define IDS_LICENSEFAILEDMSG 637
+#define IDS_BURNERROR 638
+#define IDS_LICENSESUCCESS 639
+#define IDS_LICENSEPROGRESS 640
+#define IDS_LICENSEITEMPROGRESS 641
+#define IDS_LICENSEITEMSUCCESS 642
+#define IDS_LICENSEITEMFAILED 643
+#define IDS_SKIPPED 644
+#define IDS_SCHEDULED 645
+#define IDS_PREPARINGDATA 646
+#define IDS_PREPARESUCCESS 647
+#define IDS_PREPAREFAILED 648
+#define IDS_PREPAREFAILEDMSG 649
+#define IDS_OF 650
+#define IDS_PREPAREITEMSUCCESS 651
+#define IDS_PREPAREITEMFAILED 652
+#define IDS_BURNITEMADDFAILED 653
+#define IDS_INITIALIZINGBURNER 654
+#define IDS_MASTERINGDISC 655
+#define IDS_BURNITEMSUCCESS 656
+#define IDS_WRITELEADIN 657
+#define IDS_WRITELEADOUT 658
+#define IDS_DISCOPEN 659
+#define IDS_DISCCLOSE 660
+#define IDS_BURNPROGRESS 661
+#define IDS_RELEASINGBURNER 662
+#define IDS_BURNFAILED 663
+#define IDS_BURNSUCCESS 664
+#define IDS_BURNINGCOMPLETED 665
+#define IDS_BURNINGSTOPPED 666
+#define IDS_FILENOTFOUND 667
+#define IDS_DRMNOLICENSE 668
+#define IDS_DRMNOBURNING 669
+#define IDS_DRMBURNCOUNTEXCEEDED 670
+#define IDS_NODECODER 671
+#define IDS_NOFILES 672
+#define IDS_DECODESERVICEFAILED 673
+#define IDS_LICENSEWRONGFILECOUNT 674
+#define IDS_BADFILENAME 675
+#define IDS_CACHEWRITEFAILED 676
+#define IDS_DECODESTARTFAILED 677
+#define IDS_BURNSTARTFAILED 678
+#define IDS_MASTERINGFAILED 679
+#define IDS_BEGINBURNFAILED 680
+#define IDS_ENDBURNFAILED 681
+#define IDS_WRITEAUDIOFAILED 682
+#define IDS_LIBERRORPREFIX 683
+#define IDS_DRVERRORPREFIX 684
+#define IDS_CHKDSCWRONGPARAMETER 685
+#define IDS_CHKDSCMSGPUMPFAILED 686
+#define IDS_CHKDSCDIALOGFAILED 687
+#define IDS_MB_CANCELBURNING 688
+#define IDS_TEMPORARY_FILE 689
+#define IDC_CHECK1 1001
+#define IDC_CHECK_EJECT 1001
+#define IDC_BTN_EJECT 1001
+#define IDC_CHK_AUTOCLOSE 1001
+#define IDC_PROGRESS1 1002
+#define IDC_PRG_PROGRESS 1002
+#define IDC_PRG_TOTAL 1002
+#define IDC_COMBO1 1003
+#define IDC_CMB_ERASEMETHOD 1003
+#define IDC_CHK_EJECT 1003
+#define IDC_CAPTION 1004
+#define IDC_CHK_ADDTODB 1004
+#define IDC_DESCRIPTION 1005
+#define IDC_CHK_ADDTODB2 1005
+#define IDC_CHK_HIDEWINDOW 1005
+#define IDC_PIC 1006
+#define IDC_LBL_DETECTED 1007
+#define IDC_LBL_REASON_VAL 1007
+#define IDC_LBL_REQUIRED 1008
+#define IDC_LBL_DETECTEDMEDIUM 1009
+#define IDC_LBL_REQUESTEDMEDIUM 1010
+#define IDC_LBL_HELP 1011
+#define IDC_LBL_DOTS 1012
+#define IDC_LBL_TEXT 1013
+#define IDC_BTN_ERASE 1014
+#define IDC_LBL_TIME 1015
+#define IDC_LBL_STATUS 1016
+#define IDC_LBL_REASON 1017
+#define IDC_LBL_DESCRIPTION 1018
+#define IDC_BTN_EXTENDEDVIEW 1019
+#define IDC_LST_DETAILS 1022
+#define IDC_GRP_OPTIONS 1023
+#define IDC_LBL_CURRENTOPERATION 1024
+#define IDC_LBL_ELAPSED 1025
+#define IDC_LBL_ESTIMATED 1026
+#define IDC_LBL_CAPTION 1027
+#define IDC_LBL_PERCENT 1028
+#define IDC_LBL_CURRENTOPERATION_VAL 1029
+#define IDC_LBL_ELAPSED_VAL 1030
+#define IDC_LBL_ESTIMATED_VAL 1031
+#define IDC_PIC_TESTMODE 1032
+#define IDC_BUTTON1 1033
+#define IDC_BTN_CONTINUE 1033
+#define IDS_STRING111 65535
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 114
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1036
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/Src/burnlib/resources/disc1.bmp b/Src/burnlib/resources/disc1.bmp
new file mode 100644
index 00000000..74f0364e
--- /dev/null
+++ b/Src/burnlib/resources/disc1.bmp
Binary files differ
diff --git a/Src/burnlib/resources/drive1.bmp b/Src/burnlib/resources/drive1.bmp
new file mode 100644
index 00000000..c12d3935
--- /dev/null
+++ b/Src/burnlib/resources/drive1.bmp
Binary files differ
diff --git a/Src/burnlib/resources/testmode.bmp b/Src/burnlib/resources/testmode.bmp
new file mode 100644
index 00000000..333ea0f2
--- /dev/null
+++ b/Src/burnlib/resources/testmode.bmp
Binary files differ
diff --git a/Src/burnlib/uiBurnPlayList.cpp b/Src/burnlib/uiBurnPlayList.cpp
new file mode 100644
index 00000000..622d2f6c
--- /dev/null
+++ b/Src/burnlib/uiBurnPlayList.cpp
@@ -0,0 +1,1345 @@
+#include "./uiBurnPlaylist.h"
+#include "./resource.h"
+#include <shlwapi.h>
+#include <commctrl.h>
+
+#include <strsafe.h>
+#include "./uiCheckMedium.h"
+#include "./uiUnitReady.h"
+
+#define WM_PLBURNERCOMMAND ((WM_USER) + 26)
+#define PLB_LICENSE 0
+#define PLB_DECODE 1
+#define PLB_BURN 2
+
+#define TIMER_UPDATECLOCK_ID 1979
+#define TIMER_UPDATECLOCK_INTERVAL 1000
+#define TIMER_PROGRESS_ID 1978
+#define TIMER_PROGRESS_INTERVAL 500
+
+#define COLUMN_COUNT 0
+#define COLUMN_TITLE 1
+#define COLUMN_DURATION 2
+#define COLUMN_STATUS 3
+#define COLUMN_FILENAME 4
+
+const int COLUMNWIDTH[] = {20, 220, 60, 102, 280};
+const int COLUMNALLIGN[] = {LVCFMT_LEFT, LVCFMT_LEFT, LVCFMT_CENTER, LVCFMT_LEFT, LVCFMT_LEFT};
+const int COLUMNNAME[] = {IDS_COLUMN_INDEX, IDS_COLUMN_TITLE, IDS_COLUMN_DURATION, IDS_COLUMN_STATUS, IDS_COLUMN_FILE};
+
+const COLORREF strip[] = { RGB(198, 238, 255), RGB(184, 233, 255), RGB(167, 227, 255), RGB(151, 221, 255), RGB(133, 215, 255), RGB(115, 208, 255), RGB(99, 202, 255),
+ RGB(82, 196, 255), RGB(64, 190, 255), RGB(46, 184, 255), RGB(29, 177, 255), RGB(12, 171, 255), RGB(2, 165, 255), RGB(0, 158, 255) };
+
+
+static UINT uMsgBroadcastNotify = 0;
+BurnPlaylistUI::BurnPlaylistUI(void)
+{
+ hwnd = NULL;
+ tmpfilename = NULL;
+ hTmpFile = NULL;
+ currentPercent = -1;
+ stripBmp = NULL;
+ cancelOp = FALSE;
+ workDone = NULL;
+ readyClose = TRUE;
+ ZeroMemory(&estimated, sizeof(aproxtime));
+
+}
+
+BurnPlaylistUI::~BurnPlaylistUI(void)
+{
+ if(hwnd) DestroyWindow(hwnd);
+ if (hTmpFile)
+ {
+ CloseHandle(hTmpFile);
+ hTmpFile=0;
+ }
+ if (tmpfilename)
+ {
+ DeleteFileW(tmpfilename);
+ free(tmpfilename);
+ tmpfilename=0;
+ }
+}
+
+DWORD BurnPlaylistUI::Burn(obj_primo *primoSDK, DWORD drive, DWORD maxspeed, DWORD burnFlags, BurnerPlaylist *playlist,
+ const wchar_t* tempPath, HWND ownerWnd)
+{
+ if (!primoSDK) return BURNPLAYLISTUI_PRIMOSDKNOTSET;
+ DWORD retCode;
+ extendedView = FALSE;
+ this->primoSDK = primoSDK;
+ this->drive = drive;
+ this->playlist = playlist;
+ this->maxspeed = maxspeed;
+ this->burnFlags = burnFlags;
+ this->ownerWnd = ownerWnd;
+
+ stage = PLSTAGE_READY;
+
+ wchar_t fname[64] = {0};
+ DWORD uid = GetTickCount() & 0x00FFFFFF;
+ StringCchPrintfW(fname, 64, L"wa%06I32X.tmp", uid);
+ tmpfilename = (wchar_t*)malloc((lstrlenW(tempPath) + 48)*sizeof(wchar_t));
+ if (tempPath) PathCombineW(tmpfilename, tempPath, fname);
+ else
+ {
+ wchar_t path[2048] = {0};
+ GetTempPathW(2048, path);
+ PathCombineW(tmpfilename, path, fname);
+ }
+
+ LPCDLGTEMPLATE templ = NULL;
+ HRSRC hres = FindResourceExW(hResource, MAKEINTRESOURCEW(5), MAKEINTRESOURCEW(IDD_DLG_BURNER), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
+ if (hres) templ = (LPCDLGTEMPLATE)LoadResource(hResource, hres);
+ retCode = (DWORD)DialogBoxIndirectParamW(dllInstance, templ, NULL, (DLGPROC)WndProc, (LPARAM)this);
+ return retCode;
+}
+
+
+void BurnPlaylistUI::OnInitDialog(HWND hwndDlg)
+{
+ hwnd = hwndDlg;
+ errCode = BURNPLAYLISTUI_SUCCESS;
+
+ SetPropW(hwnd, L"WABURNER", hwnd);
+ SetPropW(hwnd, L"DRIVE", (HANDLE)(INT_PTR)drive);
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHK_ADDTODB), (PRIMOSDK_TEST != (burnFlags&PRIMOSDK_TEST)));
+ CheckDlgButton(hwndDlg, IDC_CHK_ADDTODB, BST_CHECKED);
+ CheckDlgButton(hwndDlg, IDC_CHK_EJECT, BST_CHECKED);
+
+ if (ownerWnd) PostMessage(ownerWnd, WM_BURNNOTIFY, BURN_READY, (LPARAM)hwnd);
+
+ if (!uMsgBroadcastNotify) uMsgBroadcastNotify = RegisterWindowMessageA("WABURNER_BROADCAST_MSG");
+ if (uMsgBroadcastNotify) SendNotifyMessage(HWND_BROADCAST, uMsgBroadcastNotify, (WPARAM)(0xFF & drive), (LPARAM)TRUE);
+
+ SetExtendedView(extendedView);
+ SetColumns();
+ FillList();
+
+ wchar_t format[512] = {0}, buffer[512] = {0};
+ SetReadyClose(TRUE);
+
+ LoadStringW(hResource, IDS_BURNINGCDDA, format, 512);
+ StringCchPrintfW(buffer, 512, format, drive);
+
+
+ if (PRIMOSDK_TEST == (burnFlags&PRIMOSDK_TEST))
+ {
+ HANDLE hImage = NULL;
+ hImage = LoadBitmapW(hResource, MAKEINTRESOURCEW(IDB_TESTMODE));
+ if(hImage == NULL){
+ hImage = LoadBitmapW(dllInstance, MAKEINTRESOURCEW(IDB_TESTMODE));
+ }
+ SendDlgItemMessage(hwnd, IDC_PIC_TESTMODE, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hImage);
+ ShowWindow(GetDlgItem(hwnd, IDC_PIC_TESTMODE), SW_SHOW);
+ }
+
+ SetDlgItemTextW(hwnd, IDC_LBL_CAPTION, buffer);
+ SendDlgItemMessage(hwnd, IDC_PRG_TOTAL, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
+ SetProgress(0);
+
+ startedTime = GetTickCount();
+ /// estimation
+ realSpeed = 0;
+ DWORD retCode, reqspeed;
+ WAMEDIUMINFO detectedMedium;
+ retCode = GetMediumInfo(primoSDK, &drive, &detectedMedium); // required before GetDiscSpeed
+ if (PRIMOSDK_OK == retCode)
+ {
+
+ switch(maxspeed)
+ {
+ case PRIMOSDK_MAX:
+ reqspeed = 0xFFFFFFFF;
+ break;
+ case PRIMOSDK_BEST:
+ reqspeed = 0xFFFFFFF0;
+ break;
+ case PRIMOSDK_MIN:
+ reqspeed = 0x00000000;
+ break;
+ case PRIMOSDK_MEDIUM:
+ reqspeed = 0x0000FFFF;
+ break;
+ default: reqspeed = maxspeed*100;
+ }
+ // TODO: benski> should "retCode =" go before this?
+ primoSDK->GetDiscSpeed(&drive, reqspeed, &realSpeed);
+ if (PRIMOSDK_OK != retCode) realSpeed = 0;
+ }
+ if (!realSpeed) realSpeed = 4*100;
+
+ estimated.license = (DWORD)playlist->GetCount();
+ estimated.convert = playlist->GetTotalLengthMS() /(60*1000);
+ estimated.transition = 0;
+ estimated.chkdisc = 1;
+ estimated.init = 1;
+ estimated.leadin = 20;
+ estimated.burn = playlist->GetTotalLengthMS()/(realSpeed*10);
+ estimated.leadout = 20;
+ estimated.finish = 5;
+ estimatedTime = 0;
+
+ UpdateTime(TRUE);
+
+ ShowWindow(hwnd, SW_SHOWNORMAL);
+ SetForegroundWindow(hwnd);
+ BringWindowToTop(hwnd);
+ UpdateWindow(hwnd);
+
+ SetTimer(hwnd, TIMER_UPDATECLOCK_ID, TIMER_UPDATECLOCK_INTERVAL, NULL);
+
+ hTmpFile = CreateFileW(tmpfilename, GENERIC_READ|GENERIC_WRITE/*FILE_APPEND_DATA | FILE_READ_DATA*/, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | FILE_ATTRIBUTE_HIDDEN, NULL);
+ if (INVALID_HANDLE_VALUE == hTmpFile)
+ {
+ wchar_t title[64] = {0};
+ hTmpFile = NULL;
+ LoadStringW(hResource, IDS_TEMPORARY_FILE, title, 64);
+ MessageBoxW(NULL, tmpfilename, title, MB_OK);
+ ReportError(IDS_TMPCREATEFAILED, FALSE);
+ return;
+ }
+ PostMessage(hwnd, WM_PLBURNERCOMMAND, PLB_LICENSE, 0);
+ return;
+}
+
+void BurnPlaylistUI::SetColumns(void)
+{
+ HWND ctrlWnd = GetDlgItem(hwnd, IDC_LST_DETAILS);
+
+ LVCOLUMNW clmn = {0};
+ clmn.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_FMT;
+ int count = sizeof(COLUMNWIDTH) /sizeof(int);
+ wchar_t buffer[512] = {0};
+ for (int i = 0; i < count; i++)
+ {
+ LoadStringW(hResource, COLUMNNAME[i], buffer, 512);
+ clmn.cx = COLUMNWIDTH[i];
+ clmn.fmt = COLUMNALLIGN[i];
+ clmn.pszText = buffer;
+ clmn.iSubItem = i;
+ SendMessageW(ctrlWnd, LVM_INSERTCOLUMNW, i, (LPARAM)&clmn);
+ }
+
+ // extra styles
+ SendMessageW(ctrlWnd, LVM_SETEXTENDEDLISTVIEWSTYLE,
+ /*LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES |*/ LVS_EX_LABELTIP,
+ /*LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES |*/ LVS_EX_LABELTIP);
+
+}
+
+void BurnPlaylistUI::FillList(void)
+{
+ HWND ctrlWnd = GetDlgItem(hwnd, IDC_LST_DETAILS);
+ LVITEMW item = {0};
+ wchar_t buffer[128] = {0};
+ for(size_t i = 0; i < playlist->GetCount(); i++)
+ {
+ BurnerItem *bi = playlist->at(i);
+ item.mask = LVIF_TEXT | LVIF_PARAM;
+ item.iItem = (int)i;
+ item.iSubItem = COLUMN_COUNT;
+ _i64tow_s(i + 1, buffer, 128, 10);
+ item.pszText = buffer;
+ item.lParam = (LPARAM)bi;
+ SendMessage(ctrlWnd, LVM_INSERTITEMW, 0, (LPARAM)&item);
+
+ item.mask = LVIF_TEXT;
+
+ item.iSubItem = COLUMN_TITLE;
+ item.pszText = const_cast<wchar_t*>(bi->GetTitle());
+ SendMessage(ctrlWnd, LVM_SETITEMW, 0, (LPARAM)&item);
+ item.iSubItem = COLUMN_DURATION;
+ item.pszText = GetTimeString(buffer, 128, bi->GetLength()/1000);
+ SendMessage(ctrlWnd, LVM_SETITEMW, 0, (LPARAM)&item);
+ item.iSubItem = COLUMN_STATUS;
+ item.pszText = L"";
+ SendMessage(ctrlWnd, LVM_SETITEMW, 0, (LPARAM)&item);
+ item.iSubItem = COLUMN_FILENAME;
+ item.pszText = const_cast<wchar_t*>(bi->GetFullName());
+ SendMessage(ctrlWnd, LVM_SETITEMW, 0, (LPARAM)&item);
+ }
+
+}
+void BurnPlaylistUI::SetProgress(int position)
+{
+ if (currentPercent == position) return;
+ wchar_t buffer[8] = {0};
+ StringCchPrintfW(buffer, 8, L"%d%%", position);
+ SetDlgItemTextW(hwnd, IDC_LBL_PERCENT, buffer);
+ SendDlgItemMessage(hwnd, IDC_PRG_TOTAL, PBM_SETPOS, position, 0);
+ currentPercent = position;
+
+}
+void BurnPlaylistUI::UpdateTime(BOOL recalcEstimates)
+{
+ wchar_t buffer[128] = {0};
+ if (recalcEstimates)
+ {
+ estimatedTime = 0;
+ DWORD *pe = (DWORD*)&estimated;
+ for (int i = 0; i < sizeof(estimated) /sizeof(DWORD); i++) estimatedTime += pe[i];
+ SetWindowTextW(GetDlgItem(hwnd, IDC_LBL_ESTIMATED_VAL), GetTimeString(buffer, 128, estimatedTime));
+ }
+ unsigned int elapsedTime = (GetTickCount() - startedTime)/1000;
+ SetWindowTextW(GetDlgItem(hwnd, IDC_LBL_ELAPSED_VAL), GetTimeString(buffer, 128, elapsedTime));
+ if (estimatedTime <= elapsedTime)
+ {
+ estimatedTime = elapsedTime;
+ SetWindowTextW(GetDlgItem(hwnd, IDC_LBL_ESTIMATED_VAL), buffer);
+ }
+}
+
+
+void BurnPlaylistUI::ReportError(unsigned int stringCode, BOOL allowContinue)
+{
+ wchar_t buffer[512] = {0};
+ LoadStringW(hResource, stringCode, buffer, 512);
+ ReportError(buffer, allowContinue);
+}
+void BurnPlaylistUI::ReportError(const wchar_t *errorString, BOOL allowContinue)
+{
+ HWND ctrlWnd;
+ if (!allowContinue)
+ {
+ // stop timer and set progress to the end
+ estimatedTime = 0;
+ KillTimer(hwnd, TIMER_UPDATECLOCK_ID);
+ SetProgress(100);
+ // update time
+ UpdateTime(FALSE);
+ }
+ else
+ {
+ ShowWindow(GetDlgItem(hwnd, IDC_BTN_CONTINUE), SW_SHOW);
+ }
+
+ // set caption to the Burning canceled.
+ wchar_t buffer[128] = {0}, format[128] = {0};
+ LoadStringW(hResource, (allowContinue) ? IDS_BURNINGSTOPPED : IDS_BURNINGCANCELED, format, 128);
+ StringCchPrintfW(buffer, 128, format, drive);
+ SetDlgItemTextW(hwnd, IDC_LBL_CAPTION, buffer);
+ LoadStringW(hResource, IDS_REASON, buffer, 128);
+
+ // set operation info to Cancelation cause: error message
+ SetDlgItemTextW(hwnd, IDC_LBL_CURRENTOPERATION, buffer);
+ SetDlgItemTextW(hwnd, IDC_LBL_CURRENTOPERATION_VAL, errorString);
+
+ // set cancel/close button to 'close' mode and enable it
+ LoadStringW(hResource, IDS_CLOSE, buffer, 128);
+ ctrlWnd = GetDlgItem(hwnd, IDCANCEL);
+ SetWindowTextW(ctrlWnd, buffer);
+ EnableWindow(ctrlWnd, TRUE);
+ // set extended view (show all info)
+ SetExtendedView(TRUE);
+ // make some noise
+ MessageBeep(MB_ICONHAND);
+ // set status to ready for closing
+ SetReadyClose(TRUE);
+ // if somebody waiting - we done!
+ if(workDone) SetEvent(workDone);
+ if (!allowContinue) if (uMsgBroadcastNotify) SendNotifyMessage(HWND_BROADCAST, uMsgBroadcastNotify, (WPARAM)(0xFF & drive), (LPARAM)FALSE);
+}
+
+void BurnPlaylistUI::UpdateItemStatus(int index)
+{
+ LVITEMW lvi;
+ lvi.mask = LVIF_TEXT;
+ lvi.iItem = index;
+ lvi.iSubItem= COLUMN_STATUS;
+ lvi.pszText = NULL;
+ SendDlgItemMessage(hwnd, IDC_LST_DETAILS, LVM_SETITEMW, 0, (LPARAM)&lvi);
+}
+void BurnPlaylistUI::SetItemStatusText(int index, unsigned int stringCode, BOOL redraw)
+{
+ wchar_t buffer[128] = {0};
+ LoadStringW(hResource, stringCode, buffer, 128);
+ LVITEMW lvi = {0};
+ lvi.mask = LVIF_TEXT;
+ lvi.iItem = index;
+ lvi.iSubItem = COLUMN_STATUS;
+ lvi.pszText = buffer;
+
+ HWND lstWnd = GetDlgItem(hwnd, IDC_LST_DETAILS);
+ SendMessage(lstWnd, LVM_SETITEMW, 0, (LPARAM)&lvi);
+ if (redraw) ListView_RedrawItems(lstWnd, index, index);
+
+}
+void BurnPlaylistUI::SetCurrentOperation(unsigned int stringCode)
+{
+ wchar_t buffer[128] = {0};
+ LoadStringW(hResource, stringCode, buffer, 128);
+ SetDlgItemTextW(hwnd, IDC_LBL_CURRENTOPERATION_VAL, buffer);
+}
+int BurnPlaylistUI::MessageBox(unsigned int messageCode, unsigned int captionCode, unsigned int uType)
+{
+ wchar_t message[512] = {0}, caption[64] = {0};
+ LoadStringW(hResource, messageCode, message, 512);
+ LoadStringW(hResource, captionCode, caption, 64);
+ return MessageBoxW(hwnd, message, caption, uType);
+}
+void BurnPlaylistUI::OnCancel(void)
+{
+ ShowWindow(GetDlgItem(hwnd, IDC_BTN_CONTINUE), SW_HIDE);
+ if (!readyClose && workDone)
+ {
+
+ HWND btnWnd = GetDlgItem(hwnd, IDCANCEL);
+ EnableWindow(btnWnd, FALSE);
+ wchar_t message[512] = {0}, caption[64] = {0};
+ LoadStringW(hResource, IDS_MB_CANCELBURNING, message, 512);
+ LoadStringW(hResource, IDS_CONFIRMATION, caption, 64);
+ if (IDYES != MessageBoxW(hwnd, message, caption, MB_YESNO | MB_ICONQUESTION | MB_TASKMODAL | MB_SETFOREGROUND | MB_TOPMOST))
+ {
+ EnableWindow(btnWnd, TRUE);
+ return;
+ }
+
+ wchar_t buffer[64] = {0};
+ LoadStringW(hResource, IDS_BURNINGABORTEDBYUSER, buffer, 64);
+ SetDlgItemTextW(hwnd, IDC_LBL_CAPTION, buffer);
+ SetCurrentOperation(IDS_CANCELING);
+ cancelOp = TRUE;
+ MSG msg;
+ SetTimer(hwnd, TIMER_PROGRESS_ID, TIMER_PROGRESS_INTERVAL, NULL);
+ while (WAIT_TIMEOUT == WaitForSingleObject(workDone, 20))
+ {
+ while (PeekMessageW(&msg, NULL, 0,0, PM_REMOVE))
+ {
+ if(IsDialogMessage(hwnd, &msg)) continue;
+ TranslateMessage(&msg);
+ DispatchMessageW(&msg);
+ }
+ }
+ KillTimer(hwnd, TIMER_PROGRESS_ID);
+ cancelOp = FALSE;
+ CloseHandle(workDone);
+ workDone = NULL;
+ KillTimer(hwnd, TIMER_UPDATECLOCK_ID);
+ SetProgress(100);
+ estimatedTime = 0;
+ UpdateTime(FALSE);
+ if (hTmpFile)
+ {
+ CloseHandle(hTmpFile);
+ hTmpFile = NULL;
+ }
+ if (tmpfilename) DeleteFileW(tmpfilename);
+ SetReadyClose(TRUE);
+ EnableWindow(btnWnd, TRUE);
+ MessageBeep(MB_OK);
+ DWORD errorCode;
+ DWORD status = playlist->GetStatus(&errorCode);
+ if (ownerWnd) PostMessage(ownerWnd, WM_BURNNOTIFY, BURN_FINISHED, errorCode);
+ if (uMsgBroadcastNotify)
+ {
+ SendNotifyMessage(HWND_BROADCAST, uMsgBroadcastNotify, (WPARAM)(0xFF & drive), (LPARAM)FALSE);
+ }
+ if(BST_CHECKED == IsDlgButtonChecked(hwnd, IDC_CHK_AUTOCLOSE) || BST_CHECKED == IsDlgButtonChecked(hwnd, IDC_CHK_HIDEWINDOW))
+ {
+ PostMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDCANCEL, BN_CLICKED), (LPARAM)GetDlgItem(hwnd, IDCANCEL));
+ }
+ }
+ else
+ {
+ if (workDone) CloseHandle(workDone);
+ workDone = NULL;
+ if (tmpfilename) DeleteFileW(tmpfilename);
+ PostMessage(hwnd, WM_DESTROY, 0,0);
+ }
+}
+void BurnPlaylistUI::SetReadyClose(BOOL ready)
+{
+ readyClose = ready;
+ wchar_t buffer[32] = {0};
+ LoadStringW(hResource, (readyClose) ? IDS_CLOSE : IDS_CANCEL, buffer, 32);
+ SetDlgItemTextW(hwnd, IDCANCEL, buffer);
+}
+void BurnPlaylistUI::OnDestroy(void)
+{
+ if (stripBmp)
+ {
+ DeleteObject(stripBmp);
+ stripBmp = NULL;
+ }
+ if (hTmpFile)
+ {
+ CloseHandle(hTmpFile);
+ hTmpFile = NULL;
+ }
+
+ if (tmpfilename)
+ {
+ DeleteFileW(tmpfilename);
+ free(tmpfilename);
+ tmpfilename = NULL;
+ }
+ EndDialog(hwnd, errCode);
+ if (ownerWnd) PostMessage(ownerWnd, WM_BURNNOTIFY, BURN_DESTROYED, 0);
+}
+
+void BurnPlaylistUI::SetExtendedView(BOOL extView)
+{
+ extendedView = extView;
+ if (!hwnd) return;
+
+ ShowWindow(GetDlgItem(hwnd, IDC_LST_DETAILS), extView);
+ ShowWindow(GetDlgItem(hwnd, IDC_GRP_OPTIONS), extView);
+ ShowWindow(GetDlgItem(hwnd, IDC_CHK_AUTOCLOSE), extView);
+ ShowWindow(GetDlgItem(hwnd, IDC_CHK_EJECT), extView);
+ ShowWindow(GetDlgItem(hwnd, IDC_CHK_ADDTODB), extView);
+ ShowWindow(GetDlgItem(hwnd, IDC_CHK_HIDEWINDOW), extView);
+
+ RECT rw;
+ HWND ctrlWnd;
+ GetWindowRect(hwnd, &rw);
+ int height = (extView) ? 413 : 147;
+
+ SetWindowPos(hwnd, HWND_TOP, 0, 0, rw.right - rw.left, height, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
+
+ ctrlWnd = GetDlgItem(hwnd, IDC_BTN_EXTENDEDVIEW);
+ wchar_t buffer[32] = {0};
+ LoadStringW(hResource, (extView) ? IDS_SHOWLESS : IDS_SHOWMORE, buffer, 32);
+ SetWindowTextW(ctrlWnd, buffer);
+}
+
+HBITMAP BurnPlaylistUI::CreateStripBmp(HDC compDC)
+{
+ HDC hdc = CreateCompatibleDC(compDC);
+ if (!hdc) return NULL;
+
+ BITMAPINFO info;
+ // create DIB Section
+ info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ info.bmiHeader.biWidth = 1;
+ info.bmiHeader.biHeight = -14;
+ info.bmiHeader.biPlanes = 1;
+ info.bmiHeader.biBitCount = 24;
+ info.bmiHeader.biCompression = BI_RGB;
+ info.bmiHeader.biSizeImage = 0;
+ info.bmiHeader.biXPelsPerMeter = 0;
+ info.bmiHeader.biYPelsPerMeter = 0;
+ info.bmiHeader.biClrUsed = 0;
+ info.bmiHeader.biClrImportant = 0;
+ void *data;
+ HBITMAP bmp = CreateDIBSection(hdc, (const BITMAPINFO*) &info, DIB_RGB_COLORS, &data, NULL, 0);
+ if (bmp)
+ {
+ CopyMemory(data, strip, sizeof(strip));
+ }
+ DeleteDC(hdc);
+ return bmp;
+}
+
+DWORD BurnPlaylistUI::DrawList(NMLVCUSTOMDRAW* listDraw)
+{
+ switch(listDraw->nmcd.dwDrawStage)
+ {
+ case CDDS_PREPAINT:
+ return CDRF_NOTIFYITEMDRAW | CDRF_NOTIFYPOSTPAINT;
+
+ case CDDS_ITEMPREPAINT:
+ if ((int)listDraw->nmcd.dwItemSpec%2)
+ {
+ listDraw->clrTextBk = RGB(238, 238, 238);//GetSysColor(COLOR_WINDOW);
+ }
+ {
+ BurnerItem *bi = (BurnerItem*)listDraw->nmcd.lItemlParam;
+ DWORD biCode;
+ int status = bi->GetStatus(&biCode);
+ switch(status)
+ {
+ case BURNERITEM_LICENSING:
+ case BURNERITEM_DECODING:
+ case BURNERITEM_BURNING:
+ listDraw->clrText = RGB(30, 120, 40);
+ break;
+ case BURNERITEM_LICENSED:
+ case BURNERITEM_DECODED:
+ case BURNERITEM_BURNED:
+ switch(biCode)
+ {
+ case BURNERITEM_SUCCESS:
+ listDraw->clrText = RGB(10, 10, 60);
+ break;
+ case BURNERITEM_ABORTED:
+ listDraw->clrText = RGB(100, 10, 40);
+ break;
+ default:
+ listDraw->clrText = RGB(220, 0, 0);
+ break;
+ }
+ break;
+ case BURNERITEM_ABORTED:
+ listDraw->clrText = RGB(96, 24, 24);
+ break;
+ case BURNERITEM_SKIPPED:
+ listDraw->clrText = RGB(204, 204, 220);
+ break;
+ }
+ }
+ return CDRF_DODEFAULT | CDRF_NOTIFYSUBITEMDRAW;
+
+ case CDDS_ITEMPREPAINT | CDDS_SUBITEM:
+ {
+ BurnerItem *bi = (BurnerItem*)listDraw->nmcd.lItemlParam;
+ DWORD biCode;
+ int status = bi->GetStatus(&biCode);
+ switch(status)
+ {
+ case BURNERITEM_DECODING:
+ case BURNERITEM_BURNING:
+ if (listDraw->iSubItem == COLUMN_STATUS)
+ {
+ if (!stripBmp) stripBmp = CreateStripBmp(listDraw->nmcd.hdc);
+ HDC hdc = CreateCompatibleDC(listDraw->nmcd.hdc);
+ HGDIOBJ tmpBmp = SelectObject(hdc, stripBmp);
+
+ RECT rc;
+ ListView_GetSubItemRect(listDraw->nmcd.hdr.hwndFrom, (int)listDraw->nmcd.dwItemSpec, COLUMN_STATUS, LVIR_BOUNDS, &rc);
+
+ HBRUSH hb = ((int)listDraw->nmcd.dwItemSpec%2) ? CreateSolidBrush(RGB(240, 242, 245)) :GetSysColorBrush(COLOR_WINDOW);
+ RECT rb;
+ SetRect(&rb, rc.left, rc.top, rc.left + 4, rc.bottom);
+ FillRect(listDraw->nmcd.hdc, &rb, hb);
+ SetRect(&rb, rc.left + 4, rc.top, rc.right - 4, rc.top + 1);
+ FillRect(listDraw->nmcd.hdc, &rb, hb);
+ SetRect(&rb, rc.left + 4, rc.bottom - 1, rc.right - 4, rc.bottom);
+ FillRect(listDraw->nmcd.hdc, &rb, hb);
+
+ int len = int (((float)(rc.right - rc.left - 8)) * (((float)biCode)/100.0f));
+
+ SetRect(&rb, rc.left + 4 + len, rc.top, rc.right, rc.bottom);
+ FillRect(listDraw->nmcd.hdc, &rb, hb);
+
+ for (int i = rc.left + 4; i < rc.left + 4 + len; i++)
+ {
+ BitBlt(listDraw->nmcd.hdc, i, rc.top + 1, 1, rc.bottom - rc.top -2, hdc, 0, 0, SRCCOPY);
+ }
+ SelectObject(hdc, tmpBmp);
+ DeleteDC(hdc);
+ wchar_t buffer[32] = {0}, text[64] = {0};
+ LoadStringW(hResource, (BURNERITEM_DECODING == status) ? IDS_PREPARING : IDS_BURNING, buffer, 32);
+
+ StringCchPrintfW(text, 64, L"%s (%d%%)" , buffer, biCode);
+ SetTextColor(listDraw->nmcd.hdc, RGB(30, 120, 0));
+ SetBkMode(listDraw->nmcd.hdc,TRANSPARENT);
+ InflateRect(&rc, -4, 0);
+ DrawTextW(listDraw->nmcd.hdc, text, -1, &rc, DT_CENTER | DT_VCENTER |DT_END_ELLIPSIS |DT_SINGLELINE);
+ if((int)listDraw->nmcd.dwItemSpec%2) DeleteObject(hb);
+ return CDRF_SKIPDEFAULT;
+
+ }
+ break;
+ }
+ }
+
+ break;
+ default:
+ break;
+ }
+ return CDRF_DODEFAULT;
+}
+
+void BurnPlaylistUI::OnLicense(void)
+{
+ SetReadyClose(FALSE);
+ if (workDone) ResetEvent(workDone);
+ if (ownerWnd) PostMessage(ownerWnd, WM_BURNNOTIFY, BURN_WORKING, 0);
+ controlTime = GetTickCount();
+ if (!workDone) workDone = CreateEvent(NULL, FALSE, FALSE, NULL);
+ playlist->CheckLicense(OnLicensingPlaylist, this);
+}
+
+void BurnPlaylistUI::OnDecode(void)
+{
+ prevRefresh = 0;
+ SetReadyClose(FALSE);
+ if (workDone) ResetEvent(workDone);
+ if (ownerWnd) PostMessage(ownerWnd, WM_BURNNOTIFY, BURN_WORKING, 0);
+ controlTime = GetTickCount();
+ ShowWindow(GetDlgItem(hwnd, IDC_BTN_CONTINUE), SW_HIDE);
+ DWORD retCode = playlist->Decode(hTmpFile, OnDecodePlaylist, this, FALSE);
+ if (BURNERPLAYLIST_DECODESTARTING == retCode)
+ {
+ if(!workDone) workDone = CreateEvent(NULL, FALSE, FALSE, NULL);
+ }
+}
+
+void BurnPlaylistUI::OnBurn(void)
+{
+ // check disc
+ SetReadyClose(FALSE);
+ if (workDone) ResetEvent(workDone);
+ if (ownerWnd) PostMessage(ownerWnd, WM_BURNNOTIFY, BURN_WORKING, 0);
+ estimated.transition = (GetTickCount() - controlTime)/1000;
+ UpdateTime(TRUE);
+ ShowWindow(GetDlgItem(hwnd, IDC_BTN_CONTINUE), SW_HIDE);
+ DWORD totalSectors = playlist->GetTotalSectors();
+ SetReadyClose(FALSE);
+ controlTime = GetTickCount();
+ WAMEDIUMINFO mi;
+ FillMemory(&mi, sizeof(WAMEDIUMINFO), 0xFF);
+ mi.recordable = TRUE;
+ mi.isCD = TRUE;
+ mi.freeSectors = totalSectors; // plus lead-in
+ CheckMediumUI cm;
+ SetProgress(0);
+ SetCurrentOperation(IDS_CHECKINGDISC);
+ DWORD time =totalSectors/75;
+ int min = time / 60 + ((time % 60) ? 1 : 0);
+ wchar_t string[512] = {0};
+ LoadStringW(hResource, IDS_BURNREQDISC, string, 512);
+ wchar_t buffer[512] = {0};
+ StringCchPrintfW(buffer, 512, string, min);
+ DWORD retCode = cm.Check(primoSDK, &drive, &mi, buffer, FALSE, TRUE, hwnd);
+ estimated.chkdisc = (GetTickCount() - controlTime)/1000;
+ UpdateTime(TRUE);
+ switch(retCode)
+ {
+ case CHECKMEDIUMUI_MATCH:
+ {
+ // start burning
+ DWORD reqspeed;
+ unsigned int strcode;
+ switch(maxspeed)
+ {
+ case PRIMOSDK_MAX:
+ reqspeed = 0xFFFFFFFF;
+ strcode = IDS_SPEEDMAX;
+ break;
+ case PRIMOSDK_BEST:
+ reqspeed = 0xFFFFFFF0;
+ strcode = IDS_SPEEDBEST;
+ break;
+ case PRIMOSDK_MIN:
+ reqspeed = 0x00000000;
+ strcode = IDS_SPEEDMIN;
+ break;
+ case PRIMOSDK_MEDIUM:
+ reqspeed = 0xFFFFF000;
+ strcode = IDS_SPEEDMED;
+ break;
+ default:
+ reqspeed = maxspeed*100;
+ strcode = IDS_SPEED;
+ break;
+ }
+ primoSDK->GetDiscSpeed(&drive, reqspeed, &realSpeed);
+ wchar_t at[8] = {0}, spd[16] = {0}, spddesc[32] = {0};
+ StringCchPrintfW(spd, 16, L"%d.%02dx", realSpeed/100, realSpeed%100);
+
+ LoadStringW(hResource, strcode, spddesc, 32);
+ LoadStringW(hResource, IDS_BURNINGCDDA, buffer, 512);
+ StringCchPrintfW(string, 512, buffer, drive);
+ LoadStringW(hResource, IDS_AT, at, 8);
+ switch(maxspeed)
+ {
+ case PRIMOSDK_BEST:
+ StringCchPrintfW(buffer, 512, L"%s %s %s", string, at, spddesc);
+ break;
+ case PRIMOSDK_MAX:
+ case PRIMOSDK_MEDIUM:
+ case PRIMOSDK_MIN:
+ StringCchPrintfW(buffer,512, L"%s %s %s (%s)", string, at, spddesc, spd);
+ break;
+ default:
+ StringCchPrintfW(buffer,512, L"%s %s %s %s", string, at, spd, spddesc);
+ break;
+ }
+ SetDlgItemTextW(hwnd, IDC_LBL_CAPTION, buffer);
+
+ retCode = playlist->Burn(primoSDK, drive, maxspeed, burnFlags, hTmpFile,OnBurnPlaylist, this, FALSE);
+ if (BURNERPLAYLIST_BURNSTARTING == retCode)
+ {
+ if (!workDone) workDone = CreateEvent(NULL, FALSE, FALSE, NULL);
+ SetReadyClose(FALSE);
+ return;
+ }
+ break;
+ }
+ case CHECKMEDIUMUI_CANCELED: ReportError(IDS_BURNINGABORTEDBYUSER, FALSE); break;
+ case CHECKMEDIUMUI_DISCNOTSET: ReportError(IDS_CHKDSCWRONGPARAMETER, FALSE); break;
+ case CHECKMEDIUMUI_DRIVENOTSET: ReportError(IDS_CHKDSCWRONGPARAMETER, FALSE); break;
+ case CHECKMEDIUMUI_PRIMOSDKNOTSET: ReportError(IDS_CHKDSCWRONGPARAMETER, FALSE); break;
+ case CHECKMEDIUMUI_UNABLETOCREATEDIALOG: ReportError(IDS_CHKDSCDIALOGFAILED, FALSE); break;
+ case CHECKMEDIUMUI_MESSAGEPUMPERROR: ReportError(IDS_CHKDSCMSGPUMPFAILED, FALSE); break;
+ default:
+ {
+ ReportError(IDS_PRIMOINITFAILED, FALSE);
+
+ DWORD statCode, cmd, sense, asc, ascq;
+ statCode = primoSDK->UnitStatus(&drive, &cmd, &sense, &asc, &ascq);
+ wchar_t caption[64] = {0}, message[512] = {0}, myerror[128] = {0}, libprfx[32] = {0}, liberror[128] = {0}, drvprfx[32] = {0}, drverror[128] = {0};
+ LoadStringW(hResource, IDS_BURNERROR, caption, 64);
+ LoadStringW(hResource, IDS_PRIMOINITFAILED, myerror, 128);
+ LoadStringW(hResource, IDS_LIBERRORPREFIX, libprfx, 32);
+ LoadStringW(hResource, IDS_DRVERRORPREFIX, drvprfx, 32);
+ GetPrimoCodeText(liberror, 128, statCode);
+ GetUnitStatusText(drverror, 128, sense, asc, ascq);
+ StringCchPrintfW(message, 512, L"%s%s%s%s%s", myerror, libprfx, liberror, drvprfx, drverror);
+ MessageBoxW(hwnd, message, caption, MB_OK | MB_ICONEXCLAMATION);
+ }
+ break;
+ }
+ SetReadyClose(TRUE);
+ if (workDone) SetEvent(workDone);
+}
+DWORD BurnPlaylistUI::OnLicensingPlaylist(void *sender, void *userparam, DWORD notifyCode, DWORD errorCode, ULONG_PTR param)
+{
+ BurnPlaylistUI *dlg = (BurnPlaylistUI *) userparam;
+ switch (notifyCode)
+ {
+ case BURNERPLAYLIST_LICENSINGFINISHED:
+ dlg->stage = PLSTAGE_LICENSED;
+ dlg->estimated.license = (GetTickCount() - dlg->controlTime)/1000;
+ dlg->UpdateTime(TRUE);
+ KillTimer(dlg->hwnd, TIMER_PROGRESS_ID);
+ dlg->SetProgress(100);
+ switch(errorCode)
+ {
+
+ case BURNERPLAYLIST_FILENOTLICENSED: // param contains number of successfully processed files
+ dlg->ReportError(IDS_LICENSEFAILED, (param) ? TRUE : FALSE);
+ if(param)
+ {
+ dlg->estimated.convert = ((int)param)/(60*1000);
+ dlg->estimated.burn = ((int)param)/(dlg->realSpeed*10);
+ dlg->controlTime = GetTickCount();
+ dlg->MessageBox(IDS_LICENSEFAILEDMSG, IDS_BURNERROR, MB_OK | MB_ICONERROR);
+ dlg->estimated.transition += (GetTickCount() - dlg->controlTime)/1000;
+ dlg->UpdateTime(TRUE);
+ }
+ break;
+ case BURNERPLAYLIST_SUCCESS: dlg->SetCurrentOperation(IDS_LICENSESUCCESS); break;
+ case BURNERPLAYLIST_NOFILES: dlg->ReportError(IDS_NOFILES, FALSE); break;
+ case BURNERPLAYLIST_DECODESERVICEFAILED: dlg->ReportError(IDS_DECODESERVICEFAILED, FALSE); break;
+ case BURNERPLAYLIST_WRONGFILECOUNT: dlg->ReportError(IDS_LICENSEWRONGFILECOUNT, FALSE); break;
+ default: dlg->ReportError(IDS_LICENSEFAILED, FALSE); break;
+ }
+ PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_STATECHANGED, 0);
+ if (BURNERPLAYLIST_SUCCESS == errorCode) PostMessage(dlg->hwnd, WM_PLBURNERCOMMAND, PLB_DECODE, 0);
+ break;
+ case BURNERPLAYLIST_LICENSINGSTARTING:
+ switch(errorCode)
+ {
+ case BURNERPLAYLIST_ITEMADDED: dlg->SetItemStatusText((int)param, IDS_LICENSEITEMPROGRESS, TRUE); break;
+ case BURNERPLAYLIST_ADDITEMSKIPPED: dlg->SetItemStatusText((int)param, IDS_SKIPPED, TRUE); break;
+ case BURNERPLAYLIST_SUCCESS:
+ dlg->SetCurrentOperation(IDS_LICENSEPROGRESS);
+ SetTimer(dlg->hwnd, TIMER_PROGRESS_ID, 100, NULL);
+ break;
+ }
+ break;
+ case BURNERPLAYLIST_LICENSINGPROGRESS:
+ unsigned int strcode(IDS_UNKNOWN);
+ switch(errorCode)
+ {
+ case BURN_OK: dlg->SetItemStatusText((int)param, IDS_LICENSEITEMSUCCESS, TRUE); break;
+ case BURN_FILE_NOT_FOUND: dlg->SetItemStatusText((int)param, IDS_FILENOTFOUND, TRUE); break;
+ case BURN_DRM_NO_LICENSE: dlg->SetItemStatusText((int)param, IDS_DRMNOLICENSE, TRUE); break;
+ case BURN_DRM_NOT_ALLOWED: dlg->SetItemStatusText((int)param, IDS_DRMNOBURNING, TRUE); break;
+ case BURN_DRM_BURN_COUNT_EXCEEDED: dlg->SetItemStatusText((int)param, IDS_DRMBURNCOUNTEXCEEDED, TRUE); break;
+ case BURN_NO_DECODER: dlg->SetItemStatusText((int)param, IDS_NODECODER, TRUE); break;
+ default: dlg->SetItemStatusText((int)param, IDS_LICENSEITEMFAILED, TRUE); break;
+ }
+ break;
+ }
+ if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_STATECHANGED, notifyCode);
+ return (!dlg->cancelOp) ? BURNERPLAYLIST_CONTINUE : BURNERPLAYLIST_STOP;
+}
+DWORD BurnPlaylistUI::OnDecodePlaylist(void *sender, void *userparam, DWORD notifyCode, DWORD errorCode, ULONG_PTR param)
+{
+ BurnPlaylistUI *dlg = (BurnPlaylistUI *) userparam;
+ switch (notifyCode)
+ {
+ case BURNERPLAYLIST_DECODESTARTING:
+ switch(errorCode)
+ {
+ case BURNERPLAYLIST_SUCCESS:
+ dlg->SetCurrentOperation(IDS_PREPARINGDATA);
+ dlg->processed = 0;
+ dlg->count = 0;
+ if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_STATECHANGED, notifyCode);
+ break;
+ case BURNERPLAYLIST_ITEMADDED: dlg->SetItemStatusText((int)param, IDS_SCHEDULED, TRUE); dlg->count++; break;
+ case BURNERPLAYLIST_ADDITEMSKIPPED: dlg->SetItemStatusText((int)param, IDS_SKIPPED, TRUE); break;
+ }
+ break;
+ case BURNERPLAYLIST_DECODEFINISHED:
+ dlg->stage = PLSTAGE_DECODED;
+ dlg->SetProgress(100);
+ dlg->estimated.convert = (GetTickCount() - dlg->controlTime)/1000;
+ dlg->UpdateTime(TRUE);
+ dlg->controlTime = GetTickCount();
+ dlg->estimated.burn = dlg->playlist->GetStateLengthMS(BURNERITEM_DECODED, BURNERITEM_SUCCESS)/(dlg->realSpeed*10);
+ switch(errorCode)
+ {
+ case BURNERPLAYLIST_SUCCESS:
+ dlg->SetCurrentOperation(IDS_PREPARESUCCESS);
+ PostMessage(dlg->hwnd, WM_PLBURNERCOMMAND, PLB_BURN, 0);
+ break;
+ case BURNERPLAYLIST_NOFILES: dlg->ReportError(IDS_NOFILES, FALSE); break;
+ case BURNERPLAYLIST_ABORTED: dlg->ReportError(IDS_BURNINGABORTEDBYUSER, FALSE); break;
+ case BURNERPLAYLIST_DECODESERVICEFAILED: dlg->ReportError(IDS_DECODESERVICEFAILED, FALSE); break;
+ case BURNERPLAYLIST_THREADCREATEFAILED: dlg->ReportError(IDS_DECODESTARTFAILED, FALSE); break;
+
+
+ default:
+ dlg->ReportError(IDS_PREPAREFAILED, TRUE);
+ dlg->MessageBox(IDS_PREPAREFAILEDMSG, IDS_BURNERROR, MB_OK | MB_ICONERROR);
+ dlg->estimated.transition += (GetTickCount() - dlg->controlTime)/1000;
+ dlg->UpdateTime(TRUE);
+ break;
+
+ }
+ if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_STATECHANGED, notifyCode);
+ break;
+ case BURNERPLAYLIST_DECODEPROGRESS:
+ {
+ BPLDECODEINFO *info = (BPLDECODEINFO*)param;
+ switch(errorCode)
+ {
+ case BURNERPLAYLIST_DECODENEXTITEM:
+ if(!dlg->cancelOp)
+ {
+ wchar_t text[64] = {0}, of[16] = {0}, buffer[128] = {0};
+ BPLDECODEINFO *info = (BPLDECODEINFO*)param;
+ LoadStringW(hResource, IDS_PREPARINGDATA, text, 64);
+ LoadStringW(hResource, IDS_OF, of, 16);
+ StringCchPrintfW(buffer, 128, L"%s ( %d %s %d )", text, dlg->processed + 1, of, dlg->count);
+ SetDlgItemTextW(dlg->hwnd, IDC_LBL_CURRENTOPERATION_VAL, buffer);
+ if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_ITEMSTATECHANGED, info->iIndex);
+ }
+ break;
+ case BURNERPLAYLIST_DECODEITEM:
+ switch(info->iNotifyCode)
+ {
+ case BURNERITEM_DECODESTARTING:
+ ListView_RedrawItems(GetDlgItem(dlg->hwnd, IDC_LST_DETAILS), info->iIndex, info->iIndex);
+ if(!dlg->cancelOp) dlg->SetProgress((int)info->percentCompleted);
+ break;
+ case BURNERITEM_DECODEPROGRESS:
+ if (GetTickCount() - dlg->prevRefresh < 100) break;
+ dlg->UpdateItemStatus(info->iIndex);
+ if(!dlg->cancelOp)
+ {
+ dlg->SetProgress((int)info->percentCompleted);
+ if ((int)info->percentCompleted)
+ {
+ dlg->estimated.convert = (GetTickCount() - dlg->controlTime)/((int)(info->percentCompleted*10));
+ dlg->UpdateTime(TRUE);
+ }
+ }
+ dlg->prevRefresh = GetTickCount();
+ if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_ITEMDECODEPROGRESS, info->iIndex);
+ break;
+ case BURNERITEM_DECODEFINISHED:
+ switch(info->iErrorCode)
+ {
+ case BURNERITEM_SUCCESS: dlg->SetItemStatusText(info->iIndex, IDS_PREPAREITEMSUCCESS, TRUE); break;
+ case BURNERITEM_ABORTED: dlg->SetItemStatusText(info->iIndex, IDS_CANCELED, TRUE); break;
+ case BURNERITEM_BADFILENAME: dlg->SetItemStatusText(info->iIndex, IDS_BADFILENAME, TRUE); break;
+ case BURNERITEM_UNABLEOPENFILE: dlg->SetItemStatusText(info->iIndex, IDS_NODECODER, TRUE); break;
+ case BURNERITEM_WRITEERROR: dlg->SetItemStatusText(info->iIndex, IDS_CACHEWRITEFAILED, TRUE); break;
+ default:
+ dlg->SetItemStatusText(info->iIndex, IDS_PREPAREITEMFAILED, TRUE);
+ dlg->estimated.burn -= info->iInstance->GetLength()/(dlg->realSpeed*10);
+ dlg->UpdateTime(TRUE);
+ break;
+ }
+ dlg->processed++;
+ if(!dlg->cancelOp) dlg->SetProgress((int)info->percentCompleted);
+ if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_ITEMSTATECHANGED, info->iIndex);
+ break;
+ }
+ break;
+ }
+ }
+ break;
+ case BURNERPLAYLIST_DECODECANCELING: dlg->SetCurrentOperation(IDS_CANCELING); break;
+ }
+ return (!dlg->cancelOp) ? BURNERPLAYLIST_CONTINUE : BURNERPLAYLIST_STOP;
+}
+
+DWORD BurnPlaylistUI::OnBurnPlaylist(void *sender, void *userparam, DWORD notifyCode, DWORD errorCode, ULONG_PTR param)
+{
+ BurnPlaylistUI *dlg = (BurnPlaylistUI *) userparam;
+ BurnerPlaylist *playlist = (BurnerPlaylist*)sender;
+ switch (notifyCode)
+ {
+ case BURNERPLAYLIST_BURNSTARTING:
+ switch(errorCode)
+ {
+ case BURNERPLAYLIST_SUCCESS: dlg->SetCurrentOperation(IDS_MASTERINGDISC); break;
+ case BURNERPLAYLIST_ITEMADDED:
+ dlg->SetItemStatusText((int)param, IDS_SCHEDULED, TRUE);
+ if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_ITEMSTATECHANGED, param);
+ break;
+ case BURNERPLAYLIST_ADDITEMSKIPPED:
+ dlg->SetItemStatusText((int)param, IDS_SKIPPED, TRUE);
+ if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_ITEMSTATECHANGED, param);
+ break;
+ case BURNERPLAYLIST_ADDITEMFAILED:
+ dlg->SetItemStatusText((int)param, IDS_BURNITEMADDFAILED, TRUE);
+ if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_ITEMSTATECHANGED, param);
+ break;
+ case BURNERPLAYLIST_BEGINBURN: dlg->SetCurrentOperation(IDS_INITIALIZINGBURNER); break;
+ }
+ break;
+ case BURNERPLAYLIST_BURNPROGRESS:
+ switch(errorCode)
+ {
+ case BURNERPLAYLIST_WRITELEADIN:
+
+ dlg->estimated.init = (GetTickCount() - dlg->controlTime)/1000;
+ dlg->controlTime = GetTickCount();
+ dlg->UpdateTime(TRUE);
+ if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_STATECHANGED, notifyCode);
+ if (dlg->cancelOp) break;
+ dlg->SetCurrentOperation(IDS_WRITELEADIN);
+ break;
+ case BURNERPLAYLIST_WRITELEADOUT:
+ dlg->controlTime = GetTickCount();
+ if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_STATECHANGED, notifyCode);
+ if (dlg->cancelOp) break;
+ dlg->SetCurrentOperation(IDS_WRITELEADOUT);
+ break;
+ case BURNERPLAYLIST_DISCOPEN:
+ if (!dlg->cancelOp) dlg->SetCurrentOperation(IDS_DISCOPEN);
+ break;
+ case BURNERPLAYLIST_DISCCLOSE:
+ if (!dlg->cancelOp) dlg->SetCurrentOperation(IDS_DISCCLOSE);
+ break;
+ case BURNERPLAYLIST_WRITEITEMBEGIN:
+ if (((BPLRUNSTATUS*)param)->iIndex == 0)
+ {
+ dlg->estimated.leadin = (GetTickCount() - dlg->controlTime)/1000;
+ dlg->controlTime = GetTickCount();
+ }
+ ListView_RedrawItems(GetDlgItem(dlg->hwnd, IDC_LST_DETAILS), ((BPLRUNSTATUS*)param)->iIndex, ((BPLRUNSTATUS*)param)->iIndex);
+ if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_ITEMSTATECHANGED, ((BPLRUNSTATUS*)param)->iIndex);
+ break;
+ case BURNERPLAYLIST_WRITEITEMEND:
+ if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_ITEMSTATECHANGED, ((BPLRUNSTATUS*)param)->iIndex);
+ if (dlg->cancelOp) break;
+ dlg->SetItemStatusText(((BPLRUNSTATUS*)param)->iIndex, IDS_BURNITEMSUCCESS, TRUE);
+ break;
+ case BURNERPLAYLIST_WRITEDATA:
+ {
+ BPLRUNSTATUS *status = (BPLRUNSTATUS*)param;
+ int percent = (int)(status->sCurrent * 100 / status->sTotal);
+ if (!percent) break;
+ if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_ITEMBURNPROGRESS, ((BPLRUNSTATUS*)param)->iIndex);
+ if (dlg->cancelOp) break;
+ if (dlg->currentPercent != percent)
+ {
+ dlg->SetProgress(percent);
+ wchar_t format[128] = {0}, buffer[164] = {0};
+ LoadStringW(hResource, IDS_BURNPROGRESS, format, 128);
+ StringCchPrintfW(buffer, 164, format , percent);
+ SetDlgItemTextW(dlg->hwnd, IDC_LBL_CURRENTOPERATION_VAL, buffer);
+ }
+ dlg->UpdateItemStatus(((BPLRUNSTATUS*)param)->iIndex);
+ dlg->estimated.burn = (GetTickCount() - dlg->controlTime)/((int)(percent*10));
+ dlg->UpdateTime(TRUE);
+
+ }
+ break;
+ }
+ break;
+ case BURNERPLAYLIST_BURNFINISHING:
+ dlg->estimated.leadout = (GetTickCount() - dlg->controlTime)/1000;
+ dlg->UpdateTime(TRUE);
+ dlg->controlTime = GetTickCount();
+ if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_STATECHANGED, notifyCode);
+ playlist->SetEjectWhenDone((BST_CHECKED == IsDlgButtonChecked(dlg->hwnd, IDC_CHK_EJECT)) ? PRIMOSDK_OPENTRAYEJECT : 0);
+ if (dlg->cancelOp) break;
+ dlg->SetCurrentOperation(IDS_RELEASINGBURNER);
+ break;
+ case BURNERPLAYLIST_BURNFINISHED:
+ dlg->stage = PLSTAGE_BURNED;
+ dlg->estimated.finish = (GetTickCount() - dlg->controlTime)/1000;
+ dlg->SetProgress(100);
+
+ if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_FINISHED, errorCode);
+
+ switch(errorCode)
+ {
+ case BURNERPLAYLIST_ABORTED: dlg->ReportError(IDS_BURNINGABORTEDBYUSER, FALSE); return BURNERPLAYLIST_STOP;
+ case BURNERPLAYLIST_NOFILES: dlg->ReportError(IDS_NOFILES, FALSE); return BURNERPLAYLIST_STOP;
+ case BURNERPLAYLIST_ADDITEMFAILED: dlg->ReportError(IDS_MASTERINGFAILED, FALSE); return BURNERPLAYLIST_STOP;
+ case BURNERPLAYLIST_THREADCREATEFAILED: dlg->ReportError(IDS_BURNSTARTFAILED, FALSE); return BURNERPLAYLIST_STOP;
+ }
+
+ if (BURNERPLAYLIST_SUCCESS != errorCode) // rest of the errors
+ {
+ unsigned int strcode(IDS_BURNFAILED);
+ switch(errorCode)
+ {
+ case BURNERPLAYLIST_BEGINBURNFAILED: strcode = IDS_BEGINBURNFAILED; break;
+ case BURNERPLAYLIST_WRITEAUDIOFAILED: strcode = IDS_WRITEAUDIOFAILED; break;
+ case BURNERPLAYLIST_ENDBURNFAILED: strcode = IDS_ENDBURNFAILED; break;
+ }
+ dlg->ReportError(strcode, FALSE);
+
+ wchar_t caption[64] = {0}, message[512] = {0}, myerror[128] = {0}, libprfx[32] = {0}, liberror[128] = {0}, drvprfx[32] = {0}, drverror[128] = {0};
+ LoadStringW(hResource, IDS_BURNERROR, caption, 64);
+ LoadStringW(hResource, strcode, myerror, 128);
+ LoadStringW(hResource, IDS_LIBERRORPREFIX, libprfx, 32);
+ LoadStringW(hResource, IDS_DRVERRORPREFIX, drvprfx, 32);
+ GetPrimoCodeText(liberror, 128, (0x000000FF & (((DWORD)param) >> 24)));
+ GetUnitStatusText(drverror, 128, (0x000000FF & (((DWORD)param) >> 16)), (0x000000FF & (((DWORD)param) >> 8)), (0x000000FF & (DWORD)param));
+ StringCchPrintfW(message, 512, L"%s%s%s%s%s", myerror, libprfx, liberror, drvprfx, drverror);
+ MessageBoxW(dlg->hwnd, message, caption, MB_OK | MB_ICONEXCLAMATION);
+ return BURNERPLAYLIST_STOP;
+ }
+
+ // this is a happy end :)
+ if(BST_CHECKED == IsDlgButtonChecked(dlg->hwnd, IDC_CHK_ADDTODB)) dlg->playlist->AddCompilationToCDDB();
+
+ KillTimer(dlg->hwnd, TIMER_UPDATECLOCK_ID);
+ dlg->estimatedTime = 0;
+ dlg->UpdateTime(FALSE);
+ // set caption to the Burning completed.
+ {
+ wchar_t buffer[128] = {0}, format[128] = {0};
+ LoadStringW(hResource, IDS_BURNINGCOMPLETED, format, 128);
+ StringCchPrintfW(buffer, 128, format, dlg->drive);
+ SetDlgItemTextW(dlg->hwnd, IDC_LBL_CAPTION, buffer);
+ }
+
+ dlg->SetCurrentOperation(IDS_BURNSUCCESS);
+
+ dlg->SetReadyClose(TRUE);
+ if (dlg->workDone) SetEvent(dlg->workDone);
+
+ if (uMsgBroadcastNotify)
+ SendNotifyMessage(HWND_BROADCAST, uMsgBroadcastNotify, (WPARAM)(0xFF & dlg->drive), (LPARAM)FALSE);
+
+ if(BST_CHECKED == IsDlgButtonChecked(dlg->hwnd, IDC_CHK_AUTOCLOSE) ||
+ BST_CHECKED == IsDlgButtonChecked(dlg->hwnd, IDC_CHK_HIDEWINDOW))
+ {
+ PostMessage(dlg->hwnd, WM_COMMAND, MAKEWPARAM(IDCANCEL, BN_CLICKED), (LPARAM)GetDlgItem(dlg->hwnd, IDCANCEL));
+ }
+
+ MessageBeep(MB_OK);
+ break;
+ case BURNERPLAYLIST_BURNCANCELING:
+ dlg->SetItemStatusText(((BPLRUNSTATUS*)param)->iIndex,
+ (BURNERITEM_CANCELING == dlg->playlist->at(((BPLRUNSTATUS*)param)->iIndex)->GetStatus(NULL)) ? IDS_CANCELING : IDS_CANCELED,
+ TRUE);
+ if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_STATECHANGED, notifyCode);
+ break;
+ }
+ return (!dlg->cancelOp) ? BURNERPLAYLIST_CONTINUE : BURNERPLAYLIST_STOP;
+}
+
+LRESULT BurnPlaylistUI::WndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ static BurnPlaylistUI *pl = NULL;
+ switch(uMsg)
+ {
+ case WM_INITDIALOG:
+ pl = (BurnPlaylistUI*)lParam;
+ pl->OnInitDialog(hwndDlg);
+ break;
+ case WM_COMMAND:
+ switch(LOWORD(wParam))
+ {
+ case IDCANCEL:
+ pl->OnCancel();
+ break;
+ case IDC_BTN_EXTENDEDVIEW:
+ if (BN_CLICKED == HIWORD(wParam)) pl->SetExtendedView(!pl->extendedView);
+ break;
+ case IDC_BTN_CONTINUE:
+ if (BN_CLICKED == HIWORD(wParam))
+ {
+
+ wchar_t buffer[128] = {0}, format[128] = {0};
+ LoadStringW(hResource, IDS_BURNINGCDDA, format, 128);
+ StringCchPrintfW(buffer, 128, format, pl->drive);
+ SetDlgItemTextW(hwndDlg, IDC_LBL_CAPTION, buffer);
+ LoadStringW(hResource, IDS_CURRENTOPERATION, buffer, 128);
+ SetDlgItemTextW(hwndDlg, IDC_LBL_CURRENTOPERATION, buffer);
+ ShowWindow((HWND)lParam, SW_HIDE);
+ PostMessage(hwndDlg, WM_PLBURNERCOMMAND, PLB_LICENSE, 0);
+ }
+ break;
+ case IDC_CHK_AUTOCLOSE:
+ if (BN_CLICKED == HIWORD(wParam))
+ {
+ if (pl->ownerWnd)
+ PostMessage(pl->ownerWnd, WM_BURNNOTIFY,
+ BURN_CONFIGCHANGED,
+ MAKELPARAM(BURNCFG_AUTOCLOSE, (BST_CHECKED == IsDlgButtonChecked(hwndDlg, IDC_CHK_AUTOCLOSE))));
+ }
+ break;
+ case IDC_CHK_EJECT:
+ if (BN_CLICKED == HIWORD(wParam))
+ {
+ if (pl->ownerWnd)
+ PostMessage(pl->ownerWnd, WM_BURNNOTIFY,
+ BURN_CONFIGCHANGED,
+ MAKELPARAM(BURNCFG_AUTOEJECT, (BST_CHECKED == IsDlgButtonChecked(hwndDlg, IDC_CHK_EJECT))));
+ }
+ break;
+ case IDC_CHK_ADDTODB:
+ if (BN_CLICKED == HIWORD(wParam))
+ {
+ if (pl->ownerWnd)
+ PostMessage(pl->ownerWnd, WM_BURNNOTIFY,
+ BURN_CONFIGCHANGED,
+ MAKELPARAM(BURNCFG_ADDTODB, (BST_CHECKED == IsDlgButtonChecked(hwndDlg, IDC_CHK_ADDTODB))));
+ }
+ break;
+ case IDC_CHK_HIDEWINDOW:
+ if (BN_CLICKED == HIWORD(wParam))
+ {
+ if (pl->ownerWnd)
+ PostMessage(pl->ownerWnd, WM_BURNNOTIFY,
+ BURN_CONFIGCHANGED,
+ MAKELPARAM(BURNCFG_HIDEVIEW, (BST_CHECKED == IsDlgButtonChecked(hwndDlg, IDC_CHK_HIDEWINDOW))));
+ ShowWindow(hwndDlg, (BST_CHECKED == IsDlgButtonChecked(hwndDlg, IDC_CHK_HIDEWINDOW)) ? SW_HIDE : SW_SHOW);
+ }
+ break;
+ }
+ break;
+ case WM_DESTROY:
+ pl->OnDestroy();
+ break;
+ case WM_TIMER:
+ switch(wParam)
+ {
+ case TIMER_UPDATECLOCK_ID:
+ pl->UpdateTime(FALSE);
+ break;
+ case TIMER_PROGRESS_ID:
+ if (pl->currentPercent == 100) pl->currentPercent = 0;
+ pl->SetProgress(pl->currentPercent + 1);
+ break;
+ }
+ break;
+ case WM_NOTIFY:
+ if (((LPNMHDR)lParam)->idFrom == IDC_LST_DETAILS)
+ {
+ if(((LPNMHDR)lParam)->code == NM_CUSTOMDRAW)
+ {
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG)(LONG_PTR)pl->DrawList((NMLVCUSTOMDRAW*)lParam));
+ return TRUE;
+ }
+ if(((LPNMHDR)lParam)->code == LVN_ITEMCHANGED)
+ {
+ int index = (int)SendMessage(((LPNMHDR)lParam)->hwndFrom, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
+ if(index == -1) return FALSE;
+ ListView_SetItemState(((LPNMHDR)lParam)->hwndFrom, index, 0, LVIS_SELECTED | LVIS_FOCUSED);
+ return TRUE;
+ }
+ }
+ break;
+ case WM_PLBURNERCOMMAND:
+ switch(wParam)
+ {
+ case PLB_LICENSE:
+ pl->OnLicense();
+ break;
+ case PLB_DECODE:
+ pl->OnDecode();
+ break;
+ case PLB_BURN:
+ pl->OnBurn();
+ break;
+ }
+ break;
+ case WM_BURNUPDATEOWNER:
+ {
+ LONG tmpWnd = (LONG)(ULONG_PTR)pl->ownerWnd;
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, tmpWnd);
+ pl->ownerWnd = (HWND)lParam;
+ return tmpWnd;
+ }
+ case WM_BURNGETSTATUS:
+ {
+ DWORD retCode = 0;
+ switch(wParam)
+ {
+ case BURNSTATUS_DRIVE:
+ retCode = pl->drive;
+ break;
+ case BURNSTATUS_ELAPSED:
+ retCode = (GetTickCount() - pl->startedTime)/1000;
+ break;
+ case BURNSTATUS_ESTIMATED:
+ retCode = pl->estimatedTime;
+ break;
+ case BURNSTATUS_STATE:
+ retCode = pl->playlist->GetStatus(NULL);
+ break;
+ case BURNSTATUS_ERROR:
+ pl->playlist->GetStatus(&retCode);
+ break;
+ case BURNSTATUS_PROGRESS:
+ retCode = (GetTickCount() - pl->startedTime)/(pl->estimatedTime*10);
+ break;
+ }
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, retCode);
+ return retCode;
+ }
+ case WM_BURNGETITEMSTATUS:
+ {
+ DWORD retCode = 0;
+ if (((DWORD)lParam) >= pl->playlist->GetCount()) break;
+ {
+ BurnerItem *item = pl->playlist->at(lParam);
+ if (!item) break;
+ switch(wParam)
+ {
+ case BURNSTATUS_STATE:
+ retCode = item->GetStatus(NULL);
+ break;
+ case BURNSTATUS_PROGRESS:
+ case BURNSTATUS_ERROR:
+ item->GetStatus(&retCode);
+ break;
+
+ }
+ }
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, retCode);
+ return retCode;
+ }
+ case WM_BURNCONFIGCHANGED:
+ switch(wParam)
+ {
+ case BURNCFG_AUTOCLOSE:
+ CheckDlgButton(hwndDlg, IDC_CHK_AUTOCLOSE, (lParam) ? BST_CHECKED : BST_UNCHECKED);
+ break;
+ case BURNCFG_AUTOEJECT:
+ CheckDlgButton(hwndDlg, IDC_CHK_EJECT, (lParam) ? BST_CHECKED : BST_UNCHECKED);
+ break;
+ case BURNCFG_ADDTODB:
+ if (PRIMOSDK_TEST == (pl->burnFlags&PRIMOSDK_TEST)) lParam = FALSE;
+ CheckDlgButton(hwndDlg, IDC_CHK_ADDTODB, (lParam) ? BST_CHECKED : BST_UNCHECKED);
+ break;
+ case BURNCFG_HIDEVIEW:
+ CheckDlgButton(hwndDlg, IDC_CHK_HIDEWINDOW, (lParam) ? BST_CHECKED : BST_UNCHECKED);
+ break;
+ }
+ break;
+ }
+ if (uMsgBroadcastNotify && uMsgBroadcastNotify == uMsg && HIWORD(wParam) && pl && pl->playlist)
+ {
+ CHAR cLetter;
+ cLetter = (CHAR)LOWORD(wParam);
+ if (!cLetter || (cLetter == (CHAR)(0xFF & pl->drive)))
+ {
+ if (!cLetter) cLetter = (CHAR)(0xFF & pl->drive);
+ if (BURNERPLAYLIST_BURNFINISHED != pl->playlist->GetStatus(NULL))
+ SendNotifyMessage((HWND)lParam, uMsgBroadcastNotify, (WPARAM)cLetter, TRUE);
+ }
+ }
+ return 0;
+}
+
diff --git a/Src/burnlib/uiBurnPlaylist.h b/Src/burnlib/uiBurnPlaylist.h
new file mode 100644
index 00000000..3e264355
--- /dev/null
+++ b/Src/burnlib/uiBurnPlaylist.h
@@ -0,0 +1,133 @@
+#pragma once
+
+#include "./main.h"
+#include <commctrl.h>
+
+#include "./playlist.h"
+
+#define WM_BURNER ((WM_USER) + 0x400)
+
+#define WM_BURNGETSTATUS ((WM_BURNER) + 0x001)
+#define WM_BURNGETITEMSTATUS ((WM_BURNER) + 0x002)
+#define WM_BURNUPDATEOWNER ((WM_BURNER) + 0x003) // wParam = 0; lParam = ownerWnd
+#define WM_BURNCONFIGCHANGED ((WM_BURNER) + 0x004) // wParam = changed item; lParam = new value
+
+#define WM_BURNNOTIFY ((WM_BURNER) + 0x100) // wParam = Notify code, lParam notify data
+
+// Notification types
+#define BURN_READY 0xFFF // lParam = hwnd
+#define BURN_DESTROYED 0x001
+#define BURN_WORKING 0x002
+#define BURN_FINISHED 0x003
+#define BURN_STATECHANGED 0x004
+#define BURN_CONFIGCHANGED 0x005
+
+
+#define BURN_ITEMSTATECHANGED 0x010
+#define BURN_ITEMDECODEPROGRESS 0x011
+#define BURN_ITEMBURNPROGRESS 0x012
+
+// status types
+#define BURNSTATUS_DRIVE 0x0000
+#define BURNSTATUS_ELAPSED 0x0001
+#define BURNSTATUS_ESTIMATED 0x0002
+#define BURNSTATUS_PROGRESS 0x0003
+#define BURNSTATUS_STATE 0x0004
+#define BURNSTATUS_ERROR 0x0005
+
+
+#define BURNPLAYLISTUI_SUCCESS 0x0000
+#define BURNPLAYLISTUI_PRIMOSDKNOTSET 0x0105
+
+
+//stages
+#define PLSTAGE_READY 0x00
+#define PLSTAGE_LICENSED 0x01
+#define PLSTAGE_DECODED 0x02
+#define PLSTAGE_BURNED 0x03
+
+// config items
+#define BURNCFG_AUTOCLOSE 0x01
+#define BURNCFG_AUTOEJECT 0x02
+#define BURNCFG_ADDTODB 0x03
+#define BURNCFG_HIDEVIEW 0x04
+
+class BurnPlaylistUI
+{
+public:
+ BURNLIB_API BurnPlaylistUI(void);
+ BURNLIB_API ~BurnPlaylistUI(void);
+
+public:
+ BURNLIB_API DWORD Burn(obj_primo *primoSDK, DWORD drive, DWORD maxspeed, DWORD burnFlags,
+ BurnerPlaylist *playlist, const wchar_t* tempPath, HWND ownerWnd);
+
+
+protected:
+ static DWORD CALLBACK OnLicensingPlaylist(void *sender, void *userparam, DWORD notifyCode, DWORD errorCode, ULONG_PTR param);
+ static DWORD CALLBACK OnDecodePlaylist(void *sender, void *userparam, DWORD notifyCode, DWORD errorCode, ULONG_PTR param);
+ static DWORD CALLBACK OnBurnPlaylist(void *sender, void *userparam, DWORD notifyCode, DWORD errorCode, ULONG_PTR param);
+ static LRESULT CALLBACK WndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ void OnLicense(void);
+ void OnDecode(void);
+ void OnBurn(void);
+ void OnInitDialog(HWND hwndDlg);
+ void OnCancel(void);
+ void OnDestroy(void);
+ void SetExtendedView(BOOL extView);
+ void SetColumns(void);
+ void FillList(void);
+ void SetProgress(int position);
+ void UpdateTime(BOOL recalcEstimates);
+ void ReportError(unsigned int stringCode, BOOL allowContinue);
+ void ReportError(const wchar_t *errorString, BOOL allowContinue);
+ DWORD DrawList(NMLVCUSTOMDRAW* cd);
+ HBITMAP CreateStripBmp(HDC compDC);
+ void SetReadyClose(BOOL ready);
+ void UpdateItemStatus(int index);
+ void SetItemStatusText(int index, unsigned int stringCode, BOOL redraw);
+ void SetCurrentOperation(unsigned int stringCode);
+ int MessageBox(unsigned int messageCode, unsigned int captionCode, unsigned int uType);
+protected:
+
+ struct aproxtime
+ {
+ DWORD license;
+ DWORD convert;
+ DWORD transition;
+ DWORD chkdisc;
+ DWORD init;
+ DWORD leadin;
+ DWORD burn;
+ DWORD leadout;
+ DWORD finish;
+ };
+
+protected:
+ HWND hwnd;
+ HWND ownerWnd;
+ DWORD drive;
+ DWORD maxspeed;
+ DWORD burnFlags;
+ BOOL extendedView;
+ DWORD errCode;
+ obj_primo *primoSDK;
+ BurnerPlaylist *playlist;
+ unsigned int startedTime;
+ unsigned int estimatedTime;
+ wchar_t *tmpfilename;
+ HANDLE hTmpFile;
+ int currentPercent;
+ DWORD prevRefresh;
+ HBITMAP stripBmp;
+ BOOL cancelOp;
+ HANDLE workDone;
+ aproxtime estimated;
+ BOOL readyClose;
+ DWORD controlTime;
+ DWORD realSpeed;
+ DWORD stage;
+ DWORD count; // count of items to process (actual)
+ DWORD processed; // count of actually processed items
+
+}; \ No newline at end of file
diff --git a/Src/burnlib/uiCheckMedium.cpp b/Src/burnlib/uiCheckMedium.cpp
new file mode 100644
index 00000000..de2b1791
--- /dev/null
+++ b/Src/burnlib/uiCheckMedium.cpp
@@ -0,0 +1,300 @@
+#include "./uiCheckMedium.h"
+#include "./resource.h"
+#include <strsafe.h>
+
+#include "./uiEraseMedium.h"
+#include "./uiUnitReady.h"
+
+#define AINSTATE_DISABLE PRIMOSDK_LOCK
+#define AINSTATE_ENABLE PRIMOSDK_UNLOCK
+
+
+CheckMediumUI::CheckMediumUI(void)
+{
+ hwnd = NULL;
+ drive = NULL;
+ primoSDK = NULL;
+ errPrimo = 0;
+ errReady = 0;
+}
+CheckMediumUI::~CheckMediumUI(void)
+{
+ if (hwnd) DestroyWindow(hwnd);
+}
+
+DWORD CheckMediumUI::Check(obj_primo *primoSDK, DWORD *drive, WAMEDIUMINFO *medium, const wchar_t *description, BOOL disableAIN, BOOL showErase, HWND ownerWnd)
+{
+
+ if (!medium) return CHECKMEDIUMUI_DISCNOTSET;
+ if (!drive) return CHECKMEDIUMUI_DRIVENOTSET;
+ if (!primoSDK) return CHECKMEDIUMUI_PRIMOSDKNOTSET;
+ this->desiredMedium = medium;
+ this->drive = drive;
+ this->primoSDK = primoSDK;
+ this->disableAIN = (disableAIN) ? AINSTATE_DISABLE : 0 ;
+ this->showErase = showErase;
+ this->description = description;
+ this->ownerWnd = ownerWnd;
+
+ hwnd = NULL;
+ errPrimo = PRIMOSDK_OK;
+ errReady = CHECKMEDIUMUI_NOMATCH;
+
+ deadLoop = 0;
+
+ LPCDLGTEMPLATE templ = NULL;
+ HRSRC hres = FindResourceExW(hResource, MAKEINTRESOURCEW(5), MAKEINTRESOURCEW(IDD_DLG_WRONGMEDIUM), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
+ if (hres) templ = (LPCDLGTEMPLATE)LoadResource(hResource, hres);
+ HWND dlgWnd = CreateDialogIndirectParamW(dllInstance, templ, ownerWnd, (DLGPROC)WndProc, (LPARAM)this);
+
+ if (!dlgWnd) return CHECKMEDIUMUI_UNABLETOCREATEDIALOG;
+
+ MSG msg;
+ BOOL ret;
+ while( 0 != (ret = GetMessageW(&msg, hwnd, 0, 0)))
+ {
+ if (ret == -1)
+ {
+ errReady = CHECKMEDIUMUI_MESSAGEPUMPERROR;
+ break;
+ }
+ if (IsDialogMessage(hwnd, &msg)) continue;
+ TranslateMessage(&msg);
+ DispatchMessageW(&msg);
+ }
+ return errReady;
+}
+
+DWORD CheckMediumUI::Rescan(void)
+{
+ wchar_t buffer[256] = {0};
+ if (hwnd)
+ {
+ EnableWindow(GetDlgItem(hwnd, IDCANCEL), FALSE);
+
+ LoadStringW(hResource, IDS_UPDATINGDATA, buffer, 256);
+ SetWindowLong(GetDlgItem(hwnd, IDC_LBL_DETECTEDMEDIUM), GWL_STYLE, WS_CHILD | WS_VISIBLE | SS_CENTER | SS_CENTERIMAGE);
+ SetDlgItemTextW(hwnd, IDC_LBL_DETECTEDMEDIUM, buffer);
+ }
+ if (!drive) return CHECKMEDIUMUI_DRIVENOTSET;
+ if (!primoSDK) return CHECKMEDIUMUI_PRIMOSDKNOTSET;
+
+
+ UpdatingDataUI updateDlg;
+ LoadStringW(hResource, IDS_READINGDISCINFO, buffer, 256);
+ updateDlg.Show(800, buffer, TRUE, hwnd);
+
+ WAMEDIUMINFO detectedMedium;
+ ZeroMemory(&detectedMedium, sizeof(WAMEDIUMINFO));
+
+ errPrimo = GetMediumInfo(primoSDK, drive, &detectedMedium);
+ updateDlg.Hide();
+
+
+ if (PRIMOSDK_OK != errPrimo)
+ {
+
+ SetWindowLong(GetDlgItem(hwnd, IDC_LBL_DETECTEDMEDIUM), GWL_STYLE, WS_CHILD | WS_VISIBLE | SS_CENTER | SS_CENTERIMAGE);
+ LoadStringW(hResource, IDS_UNABLEGETDISCINFO, buffer, 256);
+ SetDlgItemTextW(hwnd, IDC_LBL_DETECTEDMEDIUM, buffer);
+ EnableWindow(GetDlgItem(hwnd, IDCANCEL), FALSE);
+ EnableWindow(GetDlgItem(hwnd, IDC_BTN_ERASE), FALSE);
+ EnableWindow(hwnd, FALSE);
+ if (AINSTATE_DISABLE == disableAIN && primoSDK)
+ {
+ primoSDK->UnitAIN(drive, disableAIN);
+ disableAIN = AINSTATE_ENABLE;
+ }
+ UnitReadyUI ready;
+ DWORD test = ready.Check(primoSDK, drive, FALSE, hwnd);
+ if (UNITREADYUI_DRIVEREADY == test) deadLoop++;
+ if (deadLoop == 5)
+ { /// dead loop detected - PRIMOSDK broken - recomended restart of the computer
+ errReady = CHECKMEDIUMUI_DEADLOOP;
+ if(hwnd) PostMessage(hwnd, WM_DESTROY, 0, 0);
+ return errReady;
+ }
+ EnableWindow(hwnd, TRUE);
+ UpdateWindow(hwnd);
+ switch(test)
+ {
+ case UNITREADYUI_DRIVEREADY:
+ break;
+ case UNITREADYUI_PRIMOSDKERROR:
+ errReady = CHECKMEDIUMUI_PRIMOSDKERROR;
+ break;
+ case UNITREADYUI_CANCELED:
+ errReady = CHECKMEDIUMUI_CANCELED;
+ break;
+ default:
+ errReady = CHECKMEDIUMUI_PRIMOSDKERROR;
+ break;
+
+ }
+ if (UNITREADYUI_DRIVEREADY != test)
+ {
+ if(hwnd) PostMessage(hwnd, WM_DESTROY, 0, 0);
+ return errReady;
+ }
+
+ PostMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDOK, BN_CLICKED), 0); // start other rescan
+ errReady = CHECKMEDIUMUI_DRIVENOTREADY;
+ return errReady;
+
+ }
+
+ if (hwnd)
+ {
+ EnableWindow(GetDlgItem(hwnd, IDCANCEL), TRUE);
+ SetDlgItemTextW(hwnd, IDC_LBL_DETECTEDMEDIUM, L"");
+ }
+
+ errReady = CHECKMEDIUMUI_MATCH;
+ if (CHECKMEDIUMUI_MATCH == errReady && MAXDWORD != desiredMedium->medium && desiredMedium->medium != detectedMedium.medium) errReady = CHECKMEDIUMUI_NOMATCH;
+ if (CHECKMEDIUMUI_MATCH == errReady && MAXDWORD != desiredMedium->mediumType && desiredMedium->mediumType != detectedMedium.mediumType) errReady = CHECKMEDIUMUI_NOMATCH;
+ if (CHECKMEDIUMUI_MATCH == errReady && MAXDWORD != desiredMedium->mediumFormat && desiredMedium->mediumFormat != detectedMedium.mediumFormat) errReady = CHECKMEDIUMUI_NOMATCH;
+ if (CHECKMEDIUMUI_MATCH == errReady && MAXDWORD != desiredMedium->tracks && desiredMedium->tracks != detectedMedium.tracks) errReady = CHECKMEDIUMUI_NOMATCH;
+ if (CHECKMEDIUMUI_MATCH == errReady && MAXDWORD != desiredMedium->erasable && desiredMedium->erasable != detectedMedium.erasable) errReady = CHECKMEDIUMUI_NOMATCH;
+ if (CHECKMEDIUMUI_MATCH == errReady && MAXDWORD != desiredMedium->freeSectors && desiredMedium->freeSectors > detectedMedium.freeSectors) errReady = CHECKMEDIUMUI_NOMATCH;
+ if (CHECKMEDIUMUI_MATCH == errReady && MAXDWORD != desiredMedium->usedSectors && desiredMedium->usedSectors < detectedMedium.usedSectors) errReady = CHECKMEDIUMUI_NOMATCH;
+ if (CHECKMEDIUMUI_MATCH == errReady && MAXDWORD != desiredMedium->recordable && desiredMedium->recordable != detectedMedium.recordable) errReady = CHECKMEDIUMUI_NOMATCH;
+ if (CHECKMEDIUMUI_MATCH == errReady && MAXDWORD != desiredMedium->isCD && desiredMedium->isCD != detectedMedium.isCD) errReady = CHECKMEDIUMUI_NOMATCH;
+ if (CHECKMEDIUMUI_MATCH == errReady && MAXDWORD != desiredMedium->isDCD && desiredMedium->isDCD != detectedMedium.isDCD) errReady = CHECKMEDIUMUI_NOMATCH;
+ if (CHECKMEDIUMUI_MATCH == errReady && MAXDWORD != desiredMedium->isDVD && desiredMedium->isDVD != detectedMedium.isDVD) errReady = CHECKMEDIUMUI_NOMATCH;
+ if (CHECKMEDIUMUI_MATCH == errReady && MAXDWORD != desiredMedium->isDLDVD && desiredMedium->isDLDVD != detectedMedium.isDLDVD) errReady = CHECKMEDIUMUI_NOMATCH;
+
+
+ if (CHECKMEDIUMUI_MATCH == errReady)
+ {
+ if(hwnd) PostMessage(hwnd, WM_DESTROY, 0, 0);
+ }
+ else if (hwnd)
+ {
+ wchar_t buffer[4096] = {0};
+ SetWindowLong(GetDlgItem(hwnd, IDC_LBL_DETECTEDMEDIUM), GWL_STYLE, WS_CHILD | WS_VISIBLE | SS_LEFT);
+ SetDlgItemTextW(hwnd, IDC_LBL_DETECTEDMEDIUM, GetMediumInfoText(buffer, 4096, &detectedMedium));
+
+ if (showErase) EnableWindow(GetDlgItem(hwnd, IDC_BTN_ERASE), (detectedMedium.erasable && detectedMedium.usedSectors > 0));
+ ShowWindow(hwnd, SW_SHOWNORMAL);
+ SetForegroundWindow(hwnd);
+ BringWindowToTop(hwnd);
+ MessageBeep(MB_ICONEXCLAMATION);
+ UpdateWindow(hwnd);
+ }
+ return errReady;
+}
+
+wchar_t* CheckMediumUI::GetMediumInfoText(wchar_t *buffer, unsigned int cchBuffer, WAMEDIUMINFO *info)
+{
+ buffer[0] = 0x0000;
+
+ wchar_t format[64] = {0}, freeSize[256] = {0}, usedSize[256] = {0}, medium[32] = {0}, mtype[128] = {0}, mformat[128] = {0}, erasable[32] = {0};
+ LoadStringW(hResource, IDS_DISCINFOFORMAT, format, 64);
+ LoadStringW(hResource, (info->erasable) ? IDS_DISCERASABLE : IDS_DISCNONERASABLE, erasable, 32);
+ StringCchPrintfW(buffer, cchBuffer, format, GetMediumText(medium, 32, info->medium),
+ erasable,
+ GetSizeText(freeSize, 256, info->freeSectors),
+ GetSizeText(usedSize, 256, info->usedSectors),
+ GetMediumFormatText(mformat, 128,info->mediumFormat),
+ GetMediumTypeText(mtype, 128, info->mediumType));
+ return buffer;
+}
+
+wchar_t* CheckMediumUI::GetSizeText(wchar_t *buffer, unsigned int cchBuffer, unsigned int sectors)
+{
+ wchar_t format[32] = {0},tmp[256] = {0};
+ DWORD minutes = sectors/(75*60);
+ DWORD kb = MulDiv(sectors, 2048,1024);
+ DWORD mb = kb / 1024;
+ LoadStringW(hResource, IDS_DISCSIZEFORMAT, format, 32);
+ StringCchPrintfW(tmp, 256, format, minutes, mb, sectors);
+ StringCchCatW(buffer, cchBuffer, tmp);
+ return buffer;
+}
+void CheckMediumUI::OnInitDialog(HWND hwndDlg)
+{
+ hwnd = hwndDlg;
+
+ HANDLE hImage = LoadBitmapW(hResource, MAKEINTRESOURCEW(IDB_DISC1));
+ if(hImage==NULL){
+ hImage = LoadBitmapW(dllInstance, MAKEINTRESOURCEW(IDB_DISC1));
+ }
+ SendDlgItemMessage(hwnd, IDC_PIC, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hImage);
+
+ wchar_t format[64] = {0}, buffer[66] = {0};
+
+ LoadStringW(hResource, IDS_WRONGMEDIUM, format, 64);
+ StringCchPrintfW(buffer, 64, format, (char)*drive);
+ SetWindowTextW(GetDlgItem(hwnd, IDC_CAPTION), buffer);
+ SetWindowTextW(GetDlgItem(hwnd, IDC_LBL_REQUESTEDMEDIUM), description);
+ HWND btnWnd = GetDlgItem(hwnd, IDC_BTN_ERASE);
+ EnableWindow(btnWnd, showErase);
+ ShowWindow(btnWnd, showErase);
+ Rescan();
+}
+
+void CheckMediumUI::OnCancel(void)
+{
+ wchar_t msg[256] = {0}, caption[64] = {0};
+ LoadStringW(hResource, IDS_MB_CANCELOPERATION, msg, 256);
+ LoadStringW(hResource, IDS_CONFIRMATION, caption, 64);
+ if (MessageBoxW(hwnd, msg, caption, MB_YESNO | MB_ICONQUESTION) == IDYES)
+ {
+ errReady = CHECKMEDIUMUI_CANCELED;
+ if(hwnd) DestroyWindow(hwnd);
+ hwnd = NULL;
+ }
+}
+
+void CheckMediumUI::OnDestroy(void)
+{
+ if (AINSTATE_ENABLE == disableAIN && primoSDK)
+ {
+ primoSDK->UnitAIN(drive, disableAIN);
+ disableAIN = AINSTATE_DISABLE;
+ }
+ ShowWindow(hwnd, SW_HIDE);
+ hwnd = NULL;
+ drive = NULL;
+ primoSDK = NULL;
+ deadLoop = 0;
+}
+
+void CheckMediumUI::OnEraseClicked(void)
+{
+ EraseMediumUI eraseMedium;
+ eraseMedium.Erase(*drive, FALSE, hwnd); // do not perform disc check
+ UpdateWindow(hwnd);
+ Rescan();
+}
+
+LRESULT CheckMediumUI::WndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ static CheckMediumUI *object = NULL;
+ switch(uMsg)
+ {
+ case WM_INITDIALOG:
+ object = (CheckMediumUI*)lParam;
+ object->OnInitDialog(hwndDlg);
+ break;
+ case WM_DESTROY:
+ object->OnDestroy();
+ PostQuitMessage(object->errReady);
+ break;
+ case WM_COMMAND:
+ switch(LOWORD(wParam))
+ {
+ case IDOK:
+ object->Rescan();
+ break;
+ case IDCANCEL:
+ object->OnCancel();
+ break;
+ case IDC_BTN_ERASE:
+ if (BN_CLICKED == HIWORD(wParam)) object->OnEraseClicked();
+ break;
+ }
+ break;
+ }
+ return 0;
+} \ No newline at end of file
diff --git a/Src/burnlib/uiCheckMedium.h b/Src/burnlib/uiCheckMedium.h
new file mode 100644
index 00000000..118660fc
--- /dev/null
+++ b/Src/burnlib/uiCheckMedium.h
@@ -0,0 +1,55 @@
+#pragma once
+
+#include "./main.h"
+#include "./primosdk.h"
+#define CHECKMEDIUMUI_MATCH 0x000
+#define CHECKMEDIUMUI_NOMATCH 0x001
+#define CHECKMEDIUMUI_CANCELED 0x002
+
+#define CHECKMEDIUMUI_PRIMOSDKERROR 0x101
+#define CHECKMEDIUMUI_UNABLETOCREATEDIALOG 0x102
+#define CHECKMEDIUMUI_MESSAGEPUMPERROR 0x103
+#define CHECKMEDIUMUI_DRIVENOTSET 0x104
+#define CHECKMEDIUMUI_PRIMOSDKNOTSET 0x105
+#define CHECKMEDIUMUI_DISCNOTSET 0x106
+#define CHECKMEDIUMUI_DRIVENOTREADY 0x107
+#define CHECKMEDIUMUI_DEADLOOP 0x108
+
+
+
+class CheckMediumUI
+{
+
+public:
+ BURNLIB_API CheckMediumUI(void);
+ BURNLIB_API ~CheckMediumUI(void);
+
+public:
+ BURNLIB_API DWORD Check(obj_primo *primoSDK, DWORD *drive, WAMEDIUMINFO *medium, const wchar_t *description, BOOL disableAIN, BOOL showErase, HWND ownerWnd);
+
+
+ BURNLIB_API DWORD GetPrimoError(void) { return errPrimo; }
+
+protected:
+ DWORD Rescan(void);
+ static LRESULT CALLBACK WndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ void OnInitDialog(HWND hwndDlg);
+ void OnCancel(void);
+ void OnDestroy(void);
+ void OnEraseClicked(void);
+ wchar_t* GetMediumInfoText(wchar_t *buffer, unsigned int cchBuffer, WAMEDIUMINFO *info);
+ wchar_t* GetSizeText(wchar_t *buffer, unsigned int cchBuffer, unsigned int sectors);
+
+protected:
+ HWND hwnd;
+ HWND ownerWnd;
+ WAMEDIUMINFO *desiredMedium;
+ DWORD *drive;
+ obj_primo *primoSDK;
+ DWORD errPrimo;
+ DWORD errReady;
+ BOOL disableAIN;
+ BOOL showErase;
+ DWORD deadLoop;
+ const wchar_t *description;
+}; \ No newline at end of file
diff --git a/Src/burnlib/uiEraseMedium.cpp b/Src/burnlib/uiEraseMedium.cpp
new file mode 100644
index 00000000..69ffec14
--- /dev/null
+++ b/Src/burnlib/uiEraseMedium.cpp
@@ -0,0 +1,340 @@
+#include "./uiEraseMedium.h"
+#include "api.h"
+#include <api/service/waservicefactory.h>
+#include "./resource.h"
+#include <strsafe.h>
+#include <commctrl.h>
+
+
+#include "./uiCheckMedium.h"
+
+#define ERASETIME_QUICKMODE 50 // in seconds
+#define ERASETIME_FULLMODE 510 // in seconds
+
+#define TIMER_CLOCK_ID 1979
+#define TIMER_CLOCK_INTERVAL 1000
+
+EraseMediumUI::EraseMediumUI(void)
+{
+ eraseMedium = NULL;
+
+}
+
+EraseMediumUI::~EraseMediumUI(void)
+{
+ if (eraseMedium)
+ {
+ delete(eraseMedium);
+ eraseMedium = NULL;
+ }
+}
+DWORD EraseMediumUI::SetEject(int ejectmode)
+{
+ return (eraseMedium) ? eraseMedium->SetEject(ejectmode) : 0;
+}
+
+DWORD EraseMediumUI::Erase(DWORD drive, BOOL discCheck, HWND ownerWnd)
+{
+
+ this->drive = drive;
+ this->discCheck = discCheck;
+ DWORD retCode;
+ LPCDLGTEMPLATE templ = NULL;
+
+ HRSRC hres = FindResourceExW(hResource, MAKEINTRESOURCEW(5), MAKEINTRESOURCEW(IDD_DLG_ERASEMEDIUMPREPARE), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
+ templ = (hres) ? (LPCDLGTEMPLATE)LoadResource(hResource, hres) : NULL;
+ retCode = (DWORD)DialogBoxIndirectParamW(dllInstance, templ, ownerWnd, (DLGPROC)PrepareWndProc, (LPARAM)this);
+ if (ERASEMEDIUMUI_OK != retCode) return retCode;
+
+ hres = FindResourceExW(hResource, MAKEINTRESOURCEW(5), MAKEINTRESOURCEW(IDD_DLG_ERASEMEDIUMSTATUS), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
+ templ = (hres) ? (LPCDLGTEMPLATE)LoadResource(hResource, hres) : NULL;
+ retCode = (DWORD)DialogBoxIndirectParamW(dllInstance, templ, ownerWnd, (DLGPROC)EraseWndProc, (LPARAM)this);
+ if (ERASEMEDIUM_ABORTED == retCode) return ERASEMEDIUMUI_CANCELED;
+ else if (retCode > ERASEMEDIUM_ERROR) return ERASEMEDIUMUI_ERROR;
+ return ERASEMEDIUMUI_OK;
+}
+
+void EraseMediumUI::OnPrepareInit(HWND hwndDlg)
+{
+ prepareWnd = hwndDlg;
+ wchar_t format[96] = {0}, buffer[98] = {0};
+
+ LoadStringW(hResource, IDS_SELECTERASEMETHOD, format, 96);
+ StringCchPrintfW(buffer, 98, format, drive);
+ SetDlgItemTextW(prepareWnd, IDC_CAPTION, buffer);
+ HWND cmbWnd = GetDlgItem(prepareWnd, IDC_CMB_ERASEMETHOD);
+
+ LoadStringW(hResource, IDS_QUICKERASE, buffer, 98);
+ SendMessageW(cmbWnd, CB_ADDSTRING, 0, (LPARAM)buffer);
+ LoadStringW(hResource, IDS_COMPLETEERASE, buffer, 98);
+ SendMessageW(cmbWnd, CB_ADDSTRING, 0, (LPARAM)buffer);
+ SendMessageW(cmbWnd, CB_SETCURSEL, 0, 0);
+ PostMessageW(prepareWnd, WM_COMMAND, MAKEWPARAM(IDC_CMB_ERASEMETHOD, CBN_SELCHANGE), 0);
+ ShowWindow(prepareWnd, SW_SHOWNORMAL);
+ SetForegroundWindow(prepareWnd);
+ BringWindowToTop(prepareWnd);
+}
+
+void EraseMediumUI::OnPrepareOk()
+{
+ switch(SendMessage(GetDlgItem(prepareWnd, IDC_CMB_ERASEMETHOD), CB_GETCURSEL, 0,0))
+ {
+ case 1: eraseMode = PRIMOSDK_ERASEFULL; break;
+ default: eraseMode = PRIMOSDK_ERASEQUICK; break;
+
+ }
+ if (discCheck)
+ {
+ // check that disc is erasable
+ obj_primo *primo=0;
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(obj_primo::getServiceGuid());
+ if (sf) primo = reinterpret_cast<obj_primo *>(sf->getInterface());
+ if (primo)
+ {
+ WAMEDIUMINFO mi;
+ FillMemory(&mi, sizeof(WAMEDIUMINFO), 0xFF);
+ mi.erasable = TRUE;
+ CheckMediumUI cm;
+ wchar_t buffer[256] = {0};
+ LoadStringW(hResource, IDS_ERASEREQDISC, buffer, 256);
+ DWORD retCode = cm.Check(primo, &drive, &mi, buffer, TRUE, FALSE, prepareWnd);
+
+ switch(retCode)
+ {
+
+ case CHECKMEDIUMUI_MATCH: eraseCode = ERASEMEDIUMUI_OK; break;
+ case CHECKMEDIUMUI_CANCELED: eraseCode = ERASEMEDIUMUI_CANCELED; break;
+ default: eraseCode = ERASEMEDIUMUI_PRIMOSDKERROR; break;
+ }
+
+ sf->releaseInterface(primo);
+ }
+ else
+ eraseCode = ERASEMEDIUMUI_PRIMOSDKERROR;
+ }
+ else
+ {
+ eraseCode = ERASEMEDIUMUI_OK;
+ }
+
+ EndDialog(prepareWnd, eraseCode);
+}
+void EraseMediumUI::OnEraseTimerClock(void)
+{
+ actualTime = (GetTickCount() - startTick) / 1000;
+ wchar_t time[32], *current;
+ current = time;
+ GetTimeString(current, 32, actualTime);
+ unsigned int len = lstrlenW(current);
+ current[len] = L'/';
+ len++;
+ current += len;
+ if (estimateTime < actualTime) estimateTime = actualTime;
+ GetTimeString(current, 32 - len, estimateTime);
+ SetWindowTextW(GetDlgItem(eraseWnd, IDC_LBL_TIME), time);
+ SendMessage(GetDlgItem(eraseWnd, IDC_PRG_PROGRESS), PBM_SETPOS, (int)(((float)actualTime/(float)estimateTime)*100), 0);
+}
+void EraseMediumUI::OnEraseInit(HWND hwndDlg)
+{
+ eraseWnd = hwndDlg;
+ CheckDlgButton(eraseWnd, IDC_CHECK_EJECT, BST_CHECKED);
+ EnableWindow(GetDlgItem(eraseWnd, IDC_BTN_EJECT), FALSE);
+
+ eraseMedium = new(EraseMedium);
+ if (!eraseMedium) EndDialog(eraseWnd, ERASEMEDIUMUI_UNABLETOCREATEOBJECT);
+
+
+ startTick = GetTickCount();
+ OnEraseTimerClock();
+
+ ShowWindow(eraseWnd, SW_SHOWNORMAL);
+ SetForegroundWindow(eraseWnd);
+ BringWindowToTop(eraseWnd);
+ UpdateWindow(eraseWnd);
+
+
+ SetTimer(eraseWnd, TIMER_CLOCK_ID, TIMER_CLOCK_INTERVAL, NULL);
+ SendMessage(GetDlgItem(eraseWnd, IDC_PRG_PROGRESS), PBM_SETRANGE, 0, MAKELPARAM(0, 100));
+ eraseMedium->Start(drive, eraseMode, OnEraseNotify, this, FALSE); // will catch all errors in calback
+ EnableWindow(GetDlgItem(eraseWnd, IDC_BTN_EJECT), TRUE);
+
+}
+
+void EraseMediumUI::OnEraseClose(DWORD exitCode)
+{
+ EnableWindow(GetDlgItem(eraseWnd, IDC_BTN_EJECT), FALSE);
+ if (eraseMedium)
+ {
+ HWND btnWnd = GetDlgItem(eraseWnd, IDCANCEL);
+ EnableWindow(btnWnd, FALSE);
+ eraseMedium->Stop();
+ wchar_t buffer[24] = {0};
+ LoadStringW(hResource, IDS_CLOSE, buffer, 24);
+ SetWindowTextW(btnWnd, buffer);
+ EnableWindow(btnWnd, TRUE);
+ primoCode = eraseMedium->GetErrorCode();
+ delete(eraseMedium);
+ eraseMedium = NULL;
+ }
+ eraseCode = exitCode;
+ KillTimer(eraseWnd, TIMER_CLOCK_ID);
+ estimateTime = 0; // will force it to be the same with actual
+ OnEraseTimerClock();
+}
+
+LRESULT EraseMediumUI::PrepareWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ static EraseMediumUI *object = NULL;
+ switch(uMsg)
+ {
+ case WM_INITDIALOG:
+ object = (EraseMediumUI*)lParam;
+ object->OnPrepareInit(hwndDlg);
+ break;
+ case WM_COMMAND:
+ switch(LOWORD(wParam))
+ {
+ case IDOK:
+ object->OnPrepareOk();
+ break;
+ case IDCANCEL:
+ {
+ wchar_t msg[256] = {0}, caption[64] = {0};
+ LoadStringW(hResource, IDS_MB_CANCELOPERATION, msg, 256);
+ LoadStringW(hResource, IDS_CONFIRMATION, caption, 64);
+ if (MessageBoxW(hwndDlg, msg, caption, MB_YESNO | MB_ICONQUESTION) == IDYES)
+ {
+ EndDialog(hwndDlg, LOWORD(wParam));
+ }
+ break;
+ }
+ case IDC_CMB_ERASEMETHOD:
+ switch(HIWORD(wParam))
+ {
+ case CBN_SELCHANGE:
+ switch(SendMessage(GetDlgItem(hwndDlg, IDC_CMB_ERASEMETHOD), CB_GETCURSEL, 0,0))
+ {
+ case 0:
+ object->estimateTime= ERASETIME_QUICKMODE;
+ break;
+ case 1:
+ object->estimateTime = ERASETIME_FULLMODE;
+ break;
+ default:
+ object->estimateTime =0;
+ break;
+ }
+ wchar_t time[16] = {0};
+ SetWindowTextW(GetDlgItem(hwndDlg, IDC_LBL_TIME), GetTimeString(time, 16, object->estimateTime));
+ break;
+ }
+ break;
+ }
+ break;
+ }
+ return 0;
+}
+
+LRESULT EraseMediumUI::EraseWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ static EraseMediumUI *object = NULL;
+ switch(uMsg)
+ {
+ case WM_INITDIALOG:
+ object = (EraseMediumUI*)lParam;
+ object->OnEraseInit(hwndDlg);
+ break;
+ case WM_CLOSE:
+ object->OnEraseClose((DWORD)wParam);
+ return 1;
+ case WM_COMMAND:
+ switch(LOWORD(wParam))
+ {
+ case IDCANCEL:
+ if (object->eraseMedium)
+ {
+ wchar_t msg[256] = {0}, caption[64] = {0};
+ LoadStringW(hResource, IDS_MB_CANCELOPERATION, msg, 256);
+ LoadStringW(hResource, IDS_CONFIRMATION, caption, 64);
+ if (MessageBoxW(hwndDlg, msg, caption, MB_YESNO | MB_ICONQUESTION) == IDYES) object->OnEraseClose(ERASEMEDIUM_ABORTED);
+ }
+ EndDialog(hwndDlg, object->eraseCode);
+ break;
+ case IDC_BTN_EJECT:
+ if (BN_CLICKED == HIWORD(wParam) && object->eraseMedium)
+ {
+ object->eraseMedium->SetEject(BST_CHECKED == IsDlgButtonChecked (hwndDlg,IDC_BTN_EJECT));
+ }
+ break;
+ }
+ break;
+ case WM_TIMER:
+ switch(wParam)
+ {
+ case TIMER_CLOCK_ID:
+ object->OnEraseTimerClock();
+ break;
+
+ }
+ break;
+
+ }
+ return 0;
+}
+
+DWORD EraseMediumUI::OnEraseNotify(void *sender, void *param, DWORD eraseCode, DWORD primoCode)
+{
+ EraseMediumUI *object = (EraseMediumUI*)param;
+
+ unsigned int strcode;
+ BOOL finished = FALSE;
+
+ if (ERASEMEDIUM_ERROR < eraseCode)
+ {// some error happened;
+ finished = TRUE;
+
+ switch(eraseCode)
+ {
+ case ERASEMEDIUM_ALREADYSTARTED: strcode = IDS_ALREADYERASING; break;
+ case ERASEMEDIUM_UNABLEINITPRIMO: strcode = IDS_PRIMOINITFAILED; break;
+ case ERASEMEDIUM_BEGINBURNFAILED: strcode = IDS_UNABLEINITERASE; break;
+ case ERASEMEDIUM_ENDBURNFAILED: strcode = IDS_UNABLEFINERASE; break;
+ case ERASEMEDIUM_ERASEMEDIUMFAILED: strcode = IDS_MEDIUMERASEFAILED; break;
+ case ERASEMEDIUM_DEVICENOTREADY: strcode = IDS_DRIVENOTREADY; break;
+ case ERASEMEDIUM_DISCINFOERROR: strcode = IDS_UNABLEGETDISCINFO; break;
+ case ERASEMEDIUM_DISCNOTERASABLE: strcode = IDS_DISCNONERASABLE; break;
+ default: strcode = IDS_UNKNOWNERROR; break;
+ }
+ MessageBeep(MB_ICONHAND);
+ }
+ else
+ {
+ switch(eraseCode)
+ {
+ case ERASEMEDIUM_READY: strcode = IDS_READY; break;
+ case ERASEMEDIUM_INITIALIZING: strcode = IDS_INITIALIZING; break;
+ case ERASEMEDIUM_ERASING: strcode = IDS_ERASING; break;
+ case ERASEMEDIUM_FINISHING: strcode = IDS_FINISHING; break;
+ case ERASEMEDIUM_CANCELING: strcode = IDS_CANCELING; break;
+ case ERASEMEDIUM_COMPLETED: strcode = IDS_COMPLETED; finished = TRUE; MessageBeep(MB_OK); break;
+ case ERASEMEDIUM_ABORTED: strcode = IDS_ABORTED; finished = TRUE; MessageBeep(MB_OK); break;
+ }
+
+ }
+ wchar_t buffer[224] = {0};
+ LoadStringW(hResource, strcode, buffer, 224);
+
+ if (ERASEMEDIUM_ERROR < eraseCode)
+ {
+ wchar_t txtStatus[256] = {0}, error[24] = {0};
+ LoadStringW(hResource, IDS_ERROR, error, 24);
+ StringCchPrintfW(txtStatus, 256, L"%s! %s", error, buffer);
+ }
+ else
+ {
+ SetWindowTextW(GetDlgItem(object->eraseWnd, IDC_LBL_STATUS), buffer);
+ }
+
+ if (finished) PostMessage(object->eraseWnd, WM_CLOSE, eraseCode, 0);
+ return ERASEMEDIUM_CONTINUE;
+} \ No newline at end of file
diff --git a/Src/burnlib/uiEraseMedium.h b/Src/burnlib/uiEraseMedium.h
new file mode 100644
index 00000000..bc5220e3
--- /dev/null
+++ b/Src/burnlib/uiEraseMedium.h
@@ -0,0 +1,51 @@
+#pragma once
+
+#include "./main.h"
+#include "./eraseMedium.h"
+
+#define ERASEMEDIUMUI_OK 0x000
+#define ERASEMEDIUMUI_ERROR 0x001
+#define ERASEMEDIUMUI_CANCELED 0x002
+
+#define ERASEMEDIUMUI_PRIMOSDKERROR 0x101
+#define ERASEMEDIUMUI_UNABLETOCREATEDIALOG 0x102
+#define ERASEMEDIUMUI_MESSAGEPUMPERROR 0x103
+#define ERASEMEDIUMUI_DRIVENOTSET 0x104
+#define ERASEMEDIUMUI_PRIMOSDKNOTSET 0x105
+#define ERASEMEDIUMUI_UNABLETOCREATEOBJECT 0x106
+
+class EraseMediumUI
+{
+public:
+ BURNLIB_API EraseMediumUI(void);
+ BURNLIB_API ~EraseMediumUI(void);
+public:
+ BURNLIB_API DWORD Erase(DWORD drive, BOOL discCheck, HWND ownerWnd);
+ BURNLIB_API DWORD SetEject(int ejectmode);
+
+protected:
+ static LRESULT CALLBACK PrepareWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ static LRESULT CALLBACK EraseWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ void OnPrepareInit(HWND hwndDlg);
+ void OnPrepareOk();
+ void OnEraseInit(HWND hwndDlg);
+ void OnEraseTimerClock(void);
+ void OnEraseClose(DWORD exitCode);
+ static DWORD CALLBACK OnEraseNotify(void *sender, void *param, DWORD eraseCode, DWORD primoCode);
+
+
+
+protected:
+
+ DWORD drive;
+ HWND prepareWnd;
+ HWND eraseWnd;
+ EraseMedium *eraseMedium;
+ DWORD eraseMode;
+ DWORD startTick;
+ unsigned int actualTime;
+ unsigned int estimateTime;
+ DWORD eraseCode;
+ DWORD primoCode;
+ BOOL discCheck;
+};
diff --git a/Src/burnlib/uiUnitReady.cpp b/Src/burnlib/uiUnitReady.cpp
new file mode 100644
index 00000000..0e096364
--- /dev/null
+++ b/Src/burnlib/uiUnitReady.cpp
@@ -0,0 +1,230 @@
+#include "./uiUnitReady.h"
+#include "./resource.h"
+#include <strsafe.h>
+
+#define TIMER_REFRESH_ID 1979
+#define TIMER_REFRESH_INTERVAL 300
+
+UnitReadyUI::UnitReadyUI(void)
+{
+ hwnd = NULL;
+ drive = NULL;
+ primoSDK = NULL;
+ errPrimo = 0;
+ errReady = 0;
+ updateDlg = NULL;
+}
+UnitReadyUI::~UnitReadyUI(void)
+{
+ if (updateDlg) delete(updateDlg);
+ updateDlg = NULL;
+ if (hwnd) DestroyWindow(hwnd);
+}
+
+DWORD UnitReadyUI::Check(obj_primo *primoSDK, DWORD *drive, BOOL showRetry, HWND ownerWnd)
+{
+
+ if (!drive) return UNITREADYUI_DRIVENOTSET;
+ if (!primoSDK) return UNITREADYUI_PRIMOSDKNOTSET;
+ this->drive = drive;
+ this->primoSDK = primoSDK;
+ hwnd = NULL;
+ errPrimo = PRIMOSDK_OK;
+ errReady = UNITREADYUI_NOTREADY;
+ statSense = MAXDWORD;
+ statAsc = MAXDWORD;
+ statAscQ = MAXDWORD;
+
+ if (updateDlg) delete(updateDlg);
+ updateDlg = NULL;
+
+ Rescan();
+ if (UNITREADYUI_DRIVEREADY == errReady || UNITREADYUI_CANCELED == errReady || UNITREADYUI_PRIMOSDKERROR == errReady) return errReady;
+
+ LPCDLGTEMPLATE templ = NULL;
+ HRSRC hres = FindResourceExW(hResource, MAKEINTRESOURCEW(5), MAKEINTRESOURCEW(IDD_DLG_UNITNOTREADY), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
+ if (hres) templ = (LPCDLGTEMPLATE)LoadResource(hResource, hres);
+ HWND dlgWnd = CreateDialogIndirectParamW(dllInstance, templ, ownerWnd, (DLGPROC)WndProc, (LPARAM)this);
+ if (!dlgWnd) return UNITREADYUI_UNABLETOCREATEDIALOG;
+
+ wchar_t caption[64] = {0}, buffer[48] = {0};
+ LoadStringW(hResource, IDS_UNITNOTREADY, buffer, 48);
+ StringCchPrintfW(caption, 64, buffer, (char)*drive);
+ SetWindowTextW(GetDlgItem(hwnd, IDC_CAPTION), caption);
+ ShowWindow(GetDlgItem(hwnd, IDOK), showRetry);
+
+ MSG msg;
+ BOOL ret;
+ while( 0 != (ret = GetMessageW(&msg, NULL, 0, 0)))
+ {
+ if (ret == -1)
+ {
+ errReady = UNITREADYUI_MESSAGEPUMPERROR;
+ break;
+ }
+ if (IsDialogMessage(hwnd, &msg)) continue;
+ TranslateMessage(&msg);
+ DispatchMessageW(&msg);
+ }
+
+ return errReady;
+}
+
+DWORD UnitReadyUI::Rescan(void)
+{
+ if (!drive) return UNITREADYUI_DRIVENOTSET;
+ if (!primoSDK) return UNITREADYUI_PRIMOSDKNOTSET;
+ if (hwnd) KillTimer(hwnd, TIMER_REFRESH_ID);
+
+ errPrimo = primoSDK->UnitReady(drive);
+ switch(errPrimo)
+ {
+ case PRIMOSDK_NOTREADY:
+ if (hwnd)
+ {
+ DWORD cmd(0), sense(0), asc(0), ascq(0);
+ primoSDK->UnitStatus(drive, &cmd, &sense, &asc, &ascq);
+ if (sense != statSense || asc != statAsc || ascq != statAscQ)
+ {
+ statSense = sense;
+ statAsc = asc;
+ statAscQ = ascq;
+ if ((sense == 0x02 && asc == 0x04 && ascq == 0x01) ||
+ (sense == 0x06 && asc == 0x28 && ascq == 0x00))
+ {
+ if (!updateDlg)
+ {
+ // ShowWindow(hwnd, SW_HIDE);
+ UpdateWindow(GetParent(hwnd));
+ updateDlg = new UpdatingDataUI;
+ wchar_t buffer[64] = {0};
+ LoadStringW(hResource, IDS_WAITINGFORDRIVE, buffer, 64);
+ updateDlg->Show(0, buffer, TRUE, hwnd);
+ }
+ }
+ else
+ {
+ if(updateDlg)
+ {
+ updateDlg->Hide();
+ delete(updateDlg);
+ updateDlg = NULL;
+ }
+
+ wchar_t buffer[256] = {0}, pe[512] = {0};
+ StringCchPrintfW(buffer, 256, L"%s.", GetUnitStatusText(pe, 512, sense, asc, ascq));
+ SetWindowTextW(GetDlgItem(hwnd, IDC_LBL_REASON_VAL), buffer);
+ ShowWindow(hwnd, SW_SHOW);
+ SetForegroundWindow(hwnd);
+ BringWindowToTop(hwnd);
+ UpdateWindow(hwnd);
+ MessageBeep(MB_ICONEXCLAMATION);
+
+ }
+ }
+ }
+
+
+ errReady = UNITREADYUI_NOTREADY;
+ SetTimer(hwnd, TIMER_REFRESH_ID, TIMER_REFRESH_INTERVAL, NULL);
+ break;
+ case PRIMOSDK_OK:
+ if (updateDlg)
+ {
+ updateDlg->Hide();
+ delete(updateDlg);
+ updateDlg = NULL;
+ }
+ errReady = UNITREADYUI_DRIVEREADY;
+ if(hwnd) PostMessage(hwnd, WM_DESTROY, 0, 0);
+ break;
+ default:
+ if (updateDlg)
+ {
+ updateDlg->Hide();
+ delete(updateDlg);
+ updateDlg = NULL;
+ }
+ errReady = UNITREADYUI_PRIMOSDKERROR;
+ if(hwnd) PostMessage(hwnd, WM_DESTROY, 0, 0);
+ hwnd = NULL;
+ }
+
+ return errReady;
+}
+
+void UnitReadyUI::OnInitDialog(HWND hwndDlg)
+{
+ hwnd = hwndDlg;
+ HANDLE hImage =LoadBitmapW(hResource, MAKEINTRESOURCEW(IDB_DRIVE1));
+ if(hImage==NULL){
+ hImage = LoadBitmapW(dllInstance, MAKEINTRESOURCEW(IDB_DRIVE1));
+ }
+ SendDlgItemMessage(hwnd, IDC_PIC, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hImage);
+ Rescan();
+}
+
+void UnitReadyUI::OnCancel(void)
+{
+
+ KillTimer(hwnd, TIMER_REFRESH_ID);
+ wchar_t msg[256] = {0}, caption[64] = {0};
+ LoadStringW(hResource, IDS_MB_CANCELOPERATION, msg, 256);
+ LoadStringW(hResource, IDS_CONFIRMATION, caption, 64);
+ if (MessageBoxW(hwnd, msg, caption, MB_YESNO | MB_ICONQUESTION) == IDYES)
+ {
+ errReady = UNITREADYUI_CANCELED;
+ if(hwnd) DestroyWindow(hwnd);
+ hwnd = NULL;
+ }
+ else
+ {
+ SetTimer(hwnd, TIMER_REFRESH_ID, TIMER_REFRESH_INTERVAL, NULL);
+ }
+}
+
+void UnitReadyUI::OnDestroy(void)
+{
+ ShowWindow(hwnd, SW_HIDE);
+ hwnd = NULL;
+ drive = NULL;
+ primoSDK = NULL;
+}
+
+
+LRESULT UnitReadyUI::WndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ static UnitReadyUI *object = NULL;
+ switch(uMsg)
+ {
+ case WM_INITDIALOG:
+ object = (UnitReadyUI*)lParam;
+ object->OnInitDialog(hwndDlg);
+ break;
+ case WM_DESTROY:
+ object->OnDestroy();
+ PostQuitMessage(object->errReady);
+ break;
+ case WM_COMMAND:
+ switch(LOWORD(wParam))
+ {
+ case IDOK:
+ object->Rescan();
+ break;
+ case IDCANCEL:
+ object->OnCancel();
+ break;
+ }
+ break;
+ case WM_TIMER:
+ switch(wParam)
+ {
+ case TIMER_REFRESH_ID:
+ object->Rescan();
+ break;
+ }
+ break;
+
+ }
+ return 0;
+} \ No newline at end of file
diff --git a/Src/burnlib/uiUnitReady.h b/Src/burnlib/uiUnitReady.h
new file mode 100644
index 00000000..127d56fc
--- /dev/null
+++ b/Src/burnlib/uiUnitReady.h
@@ -0,0 +1,47 @@
+#pragma once
+
+#include "./main.h"
+#include "./uiUpdatingData.h"
+#include "../primo/obj_primo.h"
+
+#define UNITREADYUI_DRIVEREADY 0x000
+#define UNITREADYUI_NOTREADY 0x001
+#define UNITREADYUI_CANCELED 0x002
+
+#define UNITREADYUI_PRIMOSDKERROR 0x101
+#define UNITREADYUI_UNABLETOCREATEDIALOG 0x102
+#define UNITREADYUI_MESSAGEPUMPERROR 0x103
+#define UNITREADYUI_DRIVENOTSET 0x104
+#define UNITREADYUI_PRIMOSDKNOTSET 0x105
+
+
+class UnitReadyUI
+{
+
+public:
+ BURNLIB_API UnitReadyUI(void);
+ BURNLIB_API ~UnitReadyUI(void);
+
+public:
+ BURNLIB_API DWORD Check(obj_primo *primoSDK, DWORD *drive, BOOL showRetry, HWND ownerWnd);
+ BURNLIB_API DWORD GetPrimoError(void) { return errPrimo; }
+
+protected:
+ DWORD Rescan(void);
+ static LRESULT CALLBACK WndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ void OnInitDialog(HWND hwndDlg);
+ void OnCancel(void);
+ void OnDestroy(void);
+
+protected:
+ HWND hwnd;
+ DWORD *drive;
+ obj_primo *primoSDK;
+ DWORD errPrimo;
+ DWORD errReady;
+ UpdatingDataUI *updateDlg;
+
+ DWORD statSense;
+ DWORD statAsc;
+ DWORD statAscQ;
+}; \ No newline at end of file
diff --git a/Src/burnlib/uiUpdatingData.cpp b/Src/burnlib/uiUpdatingData.cpp
new file mode 100644
index 00000000..2db6e482
--- /dev/null
+++ b/Src/burnlib/uiUpdatingData.cpp
@@ -0,0 +1,206 @@
+#include "./uiUpdatingData.h"
+#include "./resource.h"
+#include <strsafe.h>
+
+#define TIMER_SHOWDIALOG_ID 1979
+#define TIMER_ANIMATION_ID 1978
+#define TIMER_ANIMATION_INTERVAL 500
+
+#define ANIMATION_CUBE_SIDE 16
+#define ANIMATION_CUBE_SPACING 4
+UpdatingDataUI::UpdatingDataUI(void)
+{
+ hwnd = NULL;
+ hThread = NULL;
+ evntExit = NULL;
+ evntStarted = NULL;
+ text[0] = 0x0000;
+}
+
+
+UpdatingDataUI::~UpdatingDataUI(void)
+{
+ Hide();
+}
+
+void UpdatingDataUI::Show(int delay,HWND ownerWnd)
+{
+ wchar_t buffer[128] = {0};
+ LoadStringW(hResource, IDS_UPDATINGDATA, buffer, 128);
+ Show(delay, buffer, TRUE, ownerWnd);
+}
+void UpdatingDataUI::Show(int delay, const wchar_t* text, int animation, HWND ownerWnd)
+{
+ this->delay = delay;
+ this->ownerWnd = ownerWnd;
+ StringCchCopyW(this->text, 128, text);
+ this->animation = animation;
+ animStep = 0;
+
+ evntExit = CreateEvent(NULL, FALSE, FALSE, NULL);
+ evntStarted = CreateEvent(NULL, FALSE, FALSE, NULL);
+ DWORD id;
+ hThread = CreateThread(NULL, 0, MessagePump, this, 0, &id);
+ WaitForSingleObject(evntStarted, INFINITE);
+ CloseHandle(evntStarted);
+ evntStarted = NULL;
+}
+
+void UpdatingDataUI::Hide(void)
+{
+ if (hwnd) PostMessage(hwnd, WM_CLOSE, 0, 0);
+
+ if (evntExit)
+ {
+ WaitForSingleObject(evntExit, INFINITE);
+ CloseHandle(evntExit);
+ evntExit = NULL;
+ }
+ if (hThread)
+ {
+ CloseHandle(hThread);
+ hThread = NULL;
+ }
+}
+
+void UpdatingDataUI::OnInitDialog(HWND hwndDlg)
+{
+ hwnd = hwndDlg;
+ SetTimer(hwnd, TIMER_SHOWDIALOG_ID, delay, NULL);
+ SetEvent(evntStarted);
+}
+
+void UpdatingDataUI::OnShowTimer(void)
+{
+ KillTimer(hwnd, TIMER_SHOWDIALOG_ID);
+ RECT rect;
+ if (ownerWnd)
+ {
+ RECT ownerRect;
+ GetWindowRect(hwnd, &rect);
+ GetWindowRect(ownerWnd, &ownerRect);
+ SetWindowPos(hwnd, HWND_TOPMOST, ownerRect.left + ((ownerRect.right - ownerRect.left) - (rect.right - rect.left))/2,
+ ownerRect.top + ((ownerRect.bottom - ownerRect.top) - (rect.bottom - rect.top))/2,
+ 0,0, SWP_NOSIZE);
+ }
+ SetDlgItemTextW(hwnd, IDC_LBL_TEXT, text);
+ if (animation)
+ {
+ GetClientRect(hwnd, &rect);
+ int width = (rect.right - rect.left);
+ animStep = 0;
+ SetRect(&animRect, 10, (rect.bottom - rect.top) - ANIMATION_CUBE_SIDE - 8, width - 8, (rect.bottom - rect.top) - 10);
+ animMaxStep = ((animRect.right - animRect.left) + ANIMATION_CUBE_SPACING) / (ANIMATION_CUBE_SIDE + ANIMATION_CUBE_SPACING);
+ SetTimer(hwnd, TIMER_ANIMATION_ID, TIMER_ANIMATION_INTERVAL, NULL);
+ }
+ else
+ {
+ SetRect(&animRect, 0, 0, 0, 0);
+ animMaxStep = 0;
+ }
+ ShowWindow(hwnd, SW_SHOWNORMAL);
+ UpdateWindow(hwnd);
+}
+void UpdatingDataUI::OnAnimationTimer(void)
+{
+ animStep++;
+ if (animStep == animMaxStep) animStep = 0;
+ InvalidateRect(hwnd, &animRect, FALSE);
+}
+
+void UpdatingDataUI::OnDestroy(void)
+{
+ hwnd = NULL;
+}
+
+void UpdatingDataUI::OnPaint(PAINTSTRUCT *ps)
+{
+ if (RectVisible(ps->hdc, &animRect))
+ {
+ HBRUSH br = GetSysColorBrush(COLOR_3DFACE);
+ HBRUSH sbr = CreateSolidBrush(RGB(254, 172, 1));
+ HBRUSH oldBrush;
+ HPEN oldPen, pen = CreatePen(PS_SOLID, 2, RGB(21, 72, 9));
+ oldPen = (HPEN)SelectObject(ps->hdc, pen);
+ oldBrush = (HBRUSH)SelectObject(ps->hdc, br);
+ RECT cube = {animRect.left, animRect.top, animRect.left + ANIMATION_CUBE_SIDE, animRect.top + ANIMATION_CUBE_SIDE};
+
+ for (int i = 0; i < animMaxStep; i++)
+ {
+ SelectObject(ps->hdc, (i == animStep) ? sbr : br);
+ Rectangle(ps->hdc, cube.left, cube.top, cube.right, cube.bottom);
+ cube.left = cube.right + ANIMATION_CUBE_SPACING;
+ cube.right = cube.left + ANIMATION_CUBE_SIDE;
+ }
+ SelectObject(ps->hdc, oldPen);
+ SelectObject(ps->hdc,oldBrush);
+ // DeleteObject(br);
+ DeleteObject(sbr);
+ }
+}
+
+
+DWORD UpdatingDataUI::MessagePump(void *param)
+{
+ UpdatingDataUI *object = (UpdatingDataUI*)param;
+
+ LPCDLGTEMPLATE templ = NULL;
+ HRSRC hres = FindResourceExW(hResource, MAKEINTRESOURCEW(5), MAKEINTRESOURCEW(IDD_DLG_UPDATING), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
+ if (hres) templ = (LPCDLGTEMPLATE)LoadResource(hResource, hres);
+ HWND dlgWnd = CreateDialogIndirectParamW(dllInstance, templ, NULL, (DLGPROC)WndProc, (LPARAM)object);
+ if (!dlgWnd) return 1;
+
+ MSG msg;
+ BOOL ret;
+ while( 0 != (ret = GetMessageW(&msg, dlgWnd, 0, 0)))
+ {
+ if (ret == -1) break;
+ if (IsDialogMessage(dlgWnd, &msg)) continue;
+ TranslateMessage(&msg);
+ DispatchMessageW(&msg);
+ }
+ SetEvent(object->evntExit);
+ return 0;
+}
+LRESULT UpdatingDataUI::WndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ static UpdatingDataUI *object = NULL;
+ switch(uMsg)
+ {
+ case WM_INITDIALOG:
+ object = (UpdatingDataUI*)lParam;
+ object->OnInitDialog(hwndDlg);
+ break;
+ case WM_PAINT:
+ {
+ PAINTSTRUCT ps;
+ if (BeginPaint(hwndDlg, &ps))
+ {
+ object->OnPaint(&ps);
+ EndPaint(hwndDlg, &ps);
+ }
+ }
+ break;
+ case WM_CLOSE:
+ DestroyWindow(hwndDlg);
+ break;
+ case WM_DESTROY:
+ ShowWindow(hwndDlg, SW_HIDE);
+ PostQuitMessage(1);
+ object->OnDestroy();
+ break;
+ case WM_TIMER:
+ switch(wParam)
+ {
+ case TIMER_SHOWDIALOG_ID:
+ object->OnShowTimer();
+ break;
+ case TIMER_ANIMATION_ID:
+ object->OnAnimationTimer();
+ break;
+ }
+ break;
+
+ }
+ return 0;
+} \ No newline at end of file
diff --git a/Src/burnlib/uiUpdatingData.h b/Src/burnlib/uiUpdatingData.h
new file mode 100644
index 00000000..e490c869
--- /dev/null
+++ b/Src/burnlib/uiUpdatingData.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#include "./main.h"
+
+class UpdatingDataUI
+{
+public:
+ BURNLIB_API UpdatingDataUI(void);
+ BURNLIB_API ~UpdatingDataUI(void);
+
+public:
+ BURNLIB_API void Show(int delay, HWND ownerWnd);
+ BURNLIB_API void Show(int delay, const wchar_t* text, int animation, HWND ownerWnd);
+ BURNLIB_API void Hide(void);
+
+protected:
+ static LRESULT CALLBACK WndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ void OnInitDialog(HWND hwndDlg);
+ void OnDestroy(void);
+ void OnShowTimer(void);
+ void OnAnimationTimer(void);
+ void OnPaint(PAINTSTRUCT *ps);
+ static DWORD WINAPI MessagePump(void* param);
+
+protected:
+ HWND hwnd;
+ HWND ownerWnd;
+ HANDLE hThread;
+ HANDLE evntExit;
+ HANDLE evntStarted;
+ int delay;
+ wchar_t text[128];
+ int animation;
+ int animStep;
+ int animMaxStep;
+ RECT animRect;
+
+
+
+}; \ No newline at end of file
diff --git a/Src/burnlib/unitStatusText.cpp b/Src/burnlib/unitStatusText.cpp
new file mode 100644
index 00000000..c47107db
--- /dev/null
+++ b/Src/burnlib/unitStatusText.cpp
@@ -0,0 +1,996 @@
+#include "./main.h"
+#include "./resource.h"
+#include <strsafe.h>
+
+wchar_t* GetUnitStatusText(wchar_t *buffer, unsigned int cchBuffer, DWORD sense, DWORD asc, DWORD ascq)
+{
+ DWORD strcode = IDS_UNKNOWN;
+ switch(sense)
+ {
+ case 0x00:
+ switch(asc)
+ {
+ case 0x00:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_000000; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_000001; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_000002; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_000003; break;
+ case 0x04: strcode = IDS_DRIVEERRORCODE_000004; break;
+ case 0x05: strcode = IDS_DRIVEERRORCODE_000005; break;
+ case 0x11: strcode = IDS_DRIVEERRORCODE_000011; break;
+ case 0x12: strcode = IDS_DRIVEERRORCODE_000012; break;
+ case 0x13: strcode = IDS_DRIVEERRORCODE_000013; break;
+ case 0x14: strcode = IDS_DRIVEERRORCODE_000014; break;
+ case 0x15: strcode = IDS_DRIVEERRORCODE_000015; break;
+ case 0x16: strcode = IDS_DRIVEERRORCODE_000016; break;
+ }
+ break;
+ }
+ break;
+ case 0x01:
+ switch(asc)
+ {
+ case 0x0B:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_010B00; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_010B01; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_010B02; break;
+ }
+ break;
+ case 0x0C:
+ switch(ascq)
+ {
+ case 0x0A: strcode = IDS_DRIVEERRORCODE_010C0A; break;
+ }
+ break;
+ case 0x17:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_011700; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_011701; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_011702; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_011703; break;
+ case 0x04: strcode = IDS_DRIVEERRORCODE_011704; break;
+ case 0x05: strcode = IDS_DRIVEERRORCODE_011705; break;
+ case 0x06: strcode = IDS_DRIVEERRORCODE_011706; break;
+ case 0x07: strcode = IDS_DRIVEERRORCODE_011707; break;
+ case 0x08: strcode = IDS_DRIVEERRORCODE_011708; break;
+ case 0x09: strcode = IDS_DRIVEERRORCODE_011709; break;
+ }
+ break;
+ case 0x18:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_011800; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_011801; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_011802; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_011803; break;
+ case 0x04: strcode = IDS_DRIVEERRORCODE_011804; break;
+ case 0x05: strcode = IDS_DRIVEERRORCODE_011805; break;
+ case 0x06: strcode = IDS_DRIVEERRORCODE_011806; break;
+ case 0x07: strcode = IDS_DRIVEERRORCODE_011807; break;
+ case 0x08: strcode = IDS_DRIVEERRORCODE_011808; break;
+ }
+ break;
+ case 0x1E:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_011E00; break;
+ }
+ break;
+ case 0x37:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_013700; break;
+ }
+ break;
+ case 0x5D:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_015D00; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_015D01; break;
+ case 0xFF: strcode = IDS_DRIVEERRORCODE_015DFF; break;
+ }
+ break;
+ case 0x6A:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_016A00; break;
+ }
+ break;
+ case 0x73:
+ switch(ascq)
+ {
+ case 0x01: strcode = IDS_DRIVEERRORCODE_017301; break;
+ case 0x06: strcode = IDS_DRIVEERRORCODE_017306; break;
+ }
+ break;
+ }
+ break;
+ case 0x02:
+ switch(asc)
+ {
+ case 0x04:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_020400; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_020401; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_020402; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_020403; break;
+ case 0x04: strcode = IDS_DRIVEERRORCODE_020404; break;
+ case 0x05: strcode = IDS_DRIVEERRORCODE_020405; break;
+ case 0x06: strcode = IDS_DRIVEERRORCODE_020406; break;
+ case 0x07: strcode = IDS_DRIVEERRORCODE_020407; break;
+ case 0x08: strcode = IDS_DRIVEERRORCODE_020408; break;
+ }
+ break;
+ case 0x05:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_020500; break;
+ }
+ break;
+ case 0x06:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_020600; break;
+ }
+ break;
+ case 0x30:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_023000; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_023001; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_023002; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_023003; break;
+ case 0x04: strcode = IDS_DRIVEERRORCODE_023004; break;
+ case 0x05: strcode = IDS_DRIVEERRORCODE_023005; break;
+ case 0x07: strcode = IDS_DRIVEERRORCODE_023007; break;
+ }
+ break;
+ case 0x35:
+ switch(ascq)
+ {
+ case 0x02: strcode = IDS_DRIVEERRORCODE_023502; break;
+ }
+ break;
+ case 0x3A:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_023A00; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_023A01; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_023A02; break;
+ }
+ break;
+ case 0x3E:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_023E00; break;
+ }
+ break;
+ case 0x53:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_025300; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_025302; break;
+ }
+ break;
+ case 0x57:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_025700; break;
+ }
+ break;
+ case 0x68:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_026800; break;
+ }
+ break;
+ }
+ break;
+ case 0x03:
+ switch(asc)
+ {
+ case 0x00:
+ switch(ascq)
+ {
+ case 0x14: strcode = IDS_DRIVEERRORCODE_030014; break;
+ }
+ break;
+ case 0x02:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_030200; break;
+ case 0x80: strcode = IDS_DRIVEERRORCODE_030280; break;
+ case 0x81: strcode = IDS_DRIVEERRORCODE_030281; break;
+ case 0x82: strcode = IDS_DRIVEERRORCODE_030282; break;
+ case 0x83: strcode = IDS_DRIVEERRORCODE_030283; break;
+ }
+ break;
+ case 0x03:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_030300; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_030301; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_030302; break;
+ }
+ break;
+ case 0x06:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_030600; break;
+ }
+ break;
+ case 0x0C:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_030C00; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_030C01; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_030C02; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_030C03; break;
+ case 0x04: strcode = IDS_DRIVEERRORCODE_030C04; break;
+ case 0x05: strcode = IDS_DRIVEERRORCODE_030C05; break;
+ case 0x06: strcode = IDS_DRIVEERRORCODE_030C06; break;
+ case 0x07: strcode = IDS_DRIVEERRORCODE_030C07; break;
+ case 0x08: strcode = IDS_DRIVEERRORCODE_030C08; break;
+ case 0x09: strcode = IDS_DRIVEERRORCODE_030C09; break;
+ case 0x0A: strcode = IDS_DRIVEERRORCODE_030C0A; break;
+ }
+ break;
+ case 0x10:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_031000; break;
+ }
+ break;
+ case 0x11:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_031100; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_031101; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_031102; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_031103; break;
+ case 0x04: strcode = IDS_DRIVEERRORCODE_031104; break;
+ case 0x05: strcode = IDS_DRIVEERRORCODE_031105; break;
+ case 0x06: strcode = IDS_DRIVEERRORCODE_031106; break;
+ case 0x07: strcode = IDS_DRIVEERRORCODE_031107; break;
+ case 0x08: strcode = IDS_DRIVEERRORCODE_031108; break;
+ case 0x09: strcode = IDS_DRIVEERRORCODE_031109; break;
+ case 0x0A: strcode = IDS_DRIVEERRORCODE_03110A; break;
+ case 0x0B: strcode = IDS_DRIVEERRORCODE_03110B; break;
+ case 0x0C: strcode = IDS_DRIVEERRORCODE_03110C; break;
+ case 0x0D: strcode = IDS_DRIVEERRORCODE_03110D; break;
+ case 0x0E: strcode = IDS_DRIVEERRORCODE_03110E; break;
+ case 0x0F: strcode = IDS_DRIVEERRORCODE_03110F; break;
+ case 0x10: strcode = IDS_DRIVEERRORCODE_031110; break;
+ }
+ break;
+ case 0x12:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_031200; break;
+ }
+ break;
+ case 0x13:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_031300; break;
+ }
+ break;
+ case 0x14:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_031400; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_031401; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_031402; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_031403; break;
+ case 0x04: strcode = IDS_DRIVEERRORCODE_031404; break;
+ case 0x05: strcode = IDS_DRIVEERRORCODE_031405; break;
+ case 0x06: strcode = IDS_DRIVEERRORCODE_031406; break;
+ }
+ break;
+ case 0x15:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_031500; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_031501; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_031502; break;
+ }
+ break;
+ case 0x16:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_031600; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_031601; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_031602; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_031603; break;
+ case 0x04: strcode = IDS_DRIVEERRORCODE_031604; break;
+ }
+ break;
+ case 0x19:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_031900; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_031901; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_031902; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_031903; break;
+ }
+ break;
+ case 0x1F:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_031F00; break;
+ }
+ break;
+ case 0x2D:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_032D00; break;
+ }
+ break;
+ case 0x30:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_033000; break;
+ }
+ break;
+ case 0x31:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_033100; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_033101; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_033102; break;
+ }
+ break;
+ case 0x32:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_033200; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_033201; break;
+ }
+ break;
+ case 0x33:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_033300; break;
+ }
+ break;
+ case 0x36:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_033600; break;
+ }
+ break;
+ case 0x3B:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_033B00; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_033B01; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_033B02; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_033B03; break;
+ case 0x06: strcode = IDS_DRIVEERRORCODE_033B06; break;
+ case 0x07: strcode = IDS_DRIVEERRORCODE_033B07; break;
+ case 0x08: strcode = IDS_DRIVEERRORCODE_033B08; break;
+ case 0x09: strcode = IDS_DRIVEERRORCODE_033B09; break;
+ case 0x0A: strcode = IDS_DRIVEERRORCODE_033B0A; break;
+ case 0x0B: strcode = IDS_DRIVEERRORCODE_033B0B; break;
+ case 0x0C: strcode = IDS_DRIVEERRORCODE_033B0C; break;
+ }
+ break;
+ case 0x51:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_035100; break;
+ }
+ break;
+ case 0x52:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_035200; break;
+ }
+ break;
+ case 0x57:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_035700; break;
+ }
+ break;
+ case 0x5C:
+ switch(ascq)
+ {
+ case 0x02: strcode = IDS_DRIVEERRORCODE_035C02; break;
+ }
+ break;
+ case 0x61:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_036100; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_036101; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_036102; break;
+ }
+ break;
+ case 0x6C:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_036C00; break;
+
+ }
+ break;
+ case 0x6D:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_036D00; break;
+ }
+ break;
+ case 0x70: strcode = IDS_DRIVEERRORCODE_0370NN; break;
+ case 0x71:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_037100; break;
+ }
+ break;
+ case 0x72:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_037200; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_037201; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_037202; break;
+ }
+ break;
+ case 0x73:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_037300; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_037302; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_037303; break;
+ case 0x04: strcode = IDS_DRIVEERRORCODE_037304; break;
+ case 0x05: strcode = IDS_DRIVEERRORCODE_037305; break;
+ }
+ break;
+ }
+ break;
+ case 0x04:
+ switch(asc)
+ {
+ case 0x00:
+ switch(ascq)
+ {
+ case 0x17: strcode = IDS_DRIVEERRORCODE_040017; break;
+ }
+ break;
+ case 0x01:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_040100; break;
+ }
+ break;
+ case 0x05:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_040500; break;
+ }
+ break;
+ case 0x08:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_040800; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_040801; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_040802; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_040803; break;
+ }
+ break;
+ case 0x09:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_040900; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_040901; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_040902; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_040903; break;
+ }
+ break;
+ case 0x1B:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_041B00; break;
+ }
+ break;
+ case 0x1C:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_041C00; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_041C01; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_041C02; break;
+ }
+ break;
+ case 0x34:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_043400; break;
+ }
+ break;
+ case 0x35:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_043500; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_043503; break;
+ }
+ break;
+ case 0x3B:
+ switch(ascq)
+ {
+ case 0x04: strcode = IDS_DRIVEERRORCODE_043B04; break;
+ case 0x05: strcode = IDS_DRIVEERRORCODE_043B05; break;
+ case 0x16: strcode = IDS_DRIVEERRORCODE_043B16; break;
+ }
+ break;
+ case 0x3E:
+ switch(ascq)
+ {
+ case 0x01: strcode = IDS_DRIVEERRORCODE_043E01; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_043E02; break;
+ }
+ break;
+ case 0x44:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_044400; break;
+ }
+ break;
+ case 0x46:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_044600; break;
+ }
+ break;
+ case 0x47:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_044700; break;
+ }
+ break;
+ case 0x4A:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_044A00; break;
+ }
+ break;
+ case 0x4B:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_044B00; break;
+ }
+ break;
+ case 0x4C:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_044C00; break;
+ }
+ break;
+ case 0x53:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_045300; break;
+ }
+ break;
+ case 0x54:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_045400; break;
+ }
+ break;
+ case 0x60:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_046000; break;
+ }
+ break;
+ case 0x62:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_046200; break;
+ }
+ break;
+ case 0x65:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_046500; break;
+ }
+ break;
+ case 0x66:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_046600; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_046601; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_046602; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_046603; break;
+ }
+ break;
+ case 0x67:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_046700; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_046701; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_046702; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_046703; break;
+ case 0x04: strcode = IDS_DRIVEERRORCODE_046704; break;
+ case 0x05: strcode = IDS_DRIVEERRORCODE_046705; break;
+ case 0x06: strcode = IDS_DRIVEERRORCODE_046706; break;
+ case 0x07: strcode = IDS_DRIVEERRORCODE_046707; break;
+ }
+ break;
+ case 0x69:
+ switch(ascq)
+ {
+ case 0x01: strcode = IDS_DRIVEERRORCODE_046901; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_046902; break;
+ }
+ break;
+ case 0x6E:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_046E00; break;
+ }
+ break;
+ case 0xB6:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_04B600; break;
+ }
+ break;
+ }
+ break;
+ case 0x05:
+ switch(asc)
+ {
+ case 0x00:
+ switch(ascq)
+ {
+ case 0x11: strcode = IDS_DRIVEERRORCODE_050011; break;
+ }
+ break;
+ case 0x07:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_050700; break;
+ }
+ break;
+ case 0x1A:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_051A00; break;
+ }
+ break;
+ case 0x20:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_052000; break;
+ }
+ break;
+ case 0x21:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_052100; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_052101; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_052102; break;
+ }
+ break;
+ case 0x24:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_052400; break;
+ }
+ break;
+ case 0x25:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_052500; break;
+ }
+ break;
+ case 0x26:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_052600; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_052601; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_052602; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_052603; break;
+ case 0x04: strcode = IDS_DRIVEERRORCODE_052604; break;
+ }
+ break;
+ case 0x27:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_052700; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_052701; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_052702; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_052703; break;
+ case 0x04: strcode = IDS_DRIVEERRORCODE_052704; break;
+ case 0x05: strcode = IDS_DRIVEERRORCODE_052705; break;
+ }
+ break;
+ case 0x2B:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_052B00; break;
+ }
+ break;
+ case 0x2C:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_052C00; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_052C01; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_052C02; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_052C03; break;
+ case 0x04: strcode = IDS_DRIVEERRORCODE_052C04; break;
+ }
+ break;
+ case 0x30:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_053000; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_053002; break;
+ case 0x04: strcode = IDS_DRIVEERRORCODE_053004; break;
+ case 0x05: strcode = IDS_DRIVEERRORCODE_053005; break;
+ case 0x06: strcode = IDS_DRIVEERRORCODE_053006; break;
+ case 0x08: strcode = IDS_DRIVEERRORCODE_053008; break;
+ case 0x09: strcode = IDS_DRIVEERRORCODE_053009; break;
+ }
+ break;
+ case 0x35:
+ switch(ascq)
+ {
+ case 0x01: strcode = IDS_DRIVEERRORCODE_053501; break;
+ case 0x04: strcode = IDS_DRIVEERRORCODE_053504; break;
+ }
+ break;
+ case 0x39:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_053900; break;
+ }
+ break;
+ case 0x3D:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_053D00; break;
+ }
+ break;
+ case 0x43:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_054300; break;
+ }
+ break;
+ case 0x53:
+ switch(ascq)
+ {
+ case 0x02: strcode = IDS_DRIVEERRORCODE_055302; break;
+ }
+ break;
+ case 0x55:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_055500; break;
+ }
+ break;
+ case 0x63:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_056300; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_056301; break;
+ }
+ break;
+ case 0x64:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_056400; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_056401; break;
+ }
+ break;
+ case 0x6F:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_056F00; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_056F01; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_056F02; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_056F03; break;
+ case 0x04: strcode = IDS_DRIVEERRORCODE_056F04; break;
+ case 0x05: strcode = IDS_DRIVEERRORCODE_056F05; break;
+ }
+ break;
+ case 0x72:
+ switch(ascq)
+ {
+ case 0x03: strcode = IDS_DRIVEERRORCODE_057203; break;
+ case 0x05: strcode = IDS_DRIVEERRORCODE_057205; break;
+ }
+ break;
+ case 0x81:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_058100; break;
+ }
+ break;
+ case 0x85:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_058500; break;
+ }
+ break;
+ }
+ break;
+ case 0x06:
+ switch(asc)
+ {
+ case 0x0A:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_060A00; break;
+ }
+ break;
+ case 0x28:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_062800; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_062801; break;
+ }
+ break;
+ case 0x29:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_062900; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_062901; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_062902; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_062903; break;
+ case 0x04: strcode = IDS_DRIVEERRORCODE_062904; break;
+ }
+ break;
+ case 0x2A:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_062A00; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_062A01; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_062A02; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_062A03; break;
+ }
+ break;
+ case 0x2E:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_062E00; break;
+ }
+ break;
+ case 0x2F:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_062F00; break;
+ }
+ break;
+ case 0x3B:
+ switch(ascq)
+ {
+ case 0x0D: strcode = IDS_DRIVEERRORCODE_063B0D; break;
+ case 0x0E: strcode = IDS_DRIVEERRORCODE_063B0E; break;
+ case 0x0F: strcode = IDS_DRIVEERRORCODE_063B0F; break;
+ case 0x11: strcode = IDS_DRIVEERRORCODE_063B11; break;
+ case 0x12: strcode = IDS_DRIVEERRORCODE_063B12; break;
+ case 0x13: strcode = IDS_DRIVEERRORCODE_063B13; break;
+ case 0x14: strcode = IDS_DRIVEERRORCODE_063B14; break;
+ case 0x15: strcode = IDS_DRIVEERRORCODE_063B15; break;
+ }
+ break;
+ case 0x3F:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_063F00; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_063F01; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_063F02; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_063F03; break;
+ }
+ break;
+ case 0x55:
+ switch(ascq)
+ {
+ case 0x01: strcode = IDS_DRIVEERRORCODE_065501; break;
+ }
+ break;
+ case 0x5A:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_065A00; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_065A01; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_065A02; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_065A03; break;
+ }
+ break;
+ case 0x5B:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_065B00; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_065B01; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_065B02; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_065B03; break;
+ }
+ break;
+ case 0x5C:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_065C00; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_065C01; break;
+ }
+ break;
+ case 0x5E:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_065E00; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_065E01; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_065E02; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_065E03; break;
+ case 0x04: strcode = IDS_DRIVEERRORCODE_065E04; break;
+ }
+ break;
+ case 0x6B:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_066B00; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_066B01; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_066B02; break;
+ }
+ break;
+ }
+ break;
+ case 0x07:
+ switch(asc)
+ {
+ case 0x27:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_072700; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_072701; break;
+ case 0x02: strcode = IDS_DRIVEERRORCODE_072702; break;
+ case 0x03: strcode = IDS_DRIVEERRORCODE_072703; break;
+ case 0x04: strcode = IDS_DRIVEERRORCODE_072704; break;
+ case 0x05: strcode = IDS_DRIVEERRORCODE_072705; break;
+ }
+ break;
+ }
+ break;
+ case 0x08:
+ switch(asc)
+ {
+ case 0x21:
+ switch(ascq)
+ {
+ case 0x02: strcode = IDS_DRIVEERRORCODE_082102; break;
+ }
+ break;
+ }
+ break;
+ case 0x09:
+ switch(asc)
+ {
+ case 0x80:
+ switch(ascq)
+ {
+ case 0x00: strcode = IDS_DRIVEERRORCODE_098000; break;
+ case 0x01: strcode = IDS_DRIVEERRORCODE_098001; break;
+ case 0x05: strcode = IDS_DRIVEERRORCODE_098005; break;
+ case 0x06: strcode = IDS_DRIVEERRORCODE_098006; break;
+ case 0x07: strcode = IDS_DRIVEERRORCODE_098007; break;
+ case 0x0A: strcode = IDS_DRIVEERRORCODE_09800A; break;
+ case 0x0B: strcode = IDS_DRIVEERRORCODE_09800B; break;
+ case 0x0C: strcode = IDS_DRIVEERRORCODE_09800C; break;
+ }
+ break;
+ }
+ break;
+ }
+ LoadStringW(hResource, strcode, buffer, cchBuffer);
+ if (IDS_UNKNOWN == strcode) StringCchCatW(buffer, cchBuffer, L".");
+ return buffer;
+}
+
+