12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910 |
- #include "main.h"
- #include "./drivemngr.h"
- #include "./primosdk_helper.h"
- #include "./resource.h"
- #include "../nu/trace.h"
- #include "./dbt.h"
- #include "./spti.h"
- #include <setupapi.h>
- #include <imapi.h>
- #include <strsafe.h>
- #define LISTENER_CLASSNAME L"MLDISCLISTENER"
- #define LISTENER_WINDOWNAME L""
- #define POLLMEDIUMCHANGE_INTERVAL 2000
- #define POLLMEDIUMVALIDATE_INTERVAL 6000
- #define DMS_SUSPENDED 0x0000
- #define DMS_ACTIVE 0x0001
- #define WM_EX_QUIT (WM_APP + 1)
- typedef struct _MEDIUMINFO_I
- {
- UINT msLastPolled; // last time medium info was polled
- UINT serialNumber; // medium serialnumber
- } MEDIUMINFO_I;
- typedef struct _DRIVEINFO_I
- {
- char cLetter; // drive letter
- INT deviceNumber; // system assigned device number (unique till next reboot)
- BOOL bMediumInserted; // if TRUE mediumInfo contains valid data
- CHAR cMode; // drive mode
- DWORD dwType; // drive type
- LPWSTR pszDevName; // device name
- HANDLE hThread; // device info thread
- DWORD dwThreadId;
- MEDIUMINFO_I mediumInfo;
- } DRIVEINFO_I;
- typedef struct _DRIVEMNGR
- {
- HWND hwndListener;
- DMNPROC callback;
- UINT fState;
- CRITICAL_SECTION csLock;
- DRIVEINFO_I *pDrives;
- INT nCount;
- INT nAlloc;
- HANDLE hPollingThread;
- DWORD dwPollingThread;
- } DRIVEMNGR;
- typedef struct _DEVICEINFO
- {
- CHAR cLetter;
- LPWSTR pszDevName;
- WCHAR szTargetPath[128];
- WCHAR szVolumeName[64];
- DWORD dwType;
- INT deviceNumber;
- INT opCode;
- } DEVICEINFO;
- static DRIVEMNGR *pMngr = NULL;
- static void CALLBACK APC_CheckDrives(ULONG_PTR param);
- static void CALLBACK APC_IsMediumChanged(ULONG_PTR param);
- static void CALLBACK APC_GetUnitInfo(ULONG_PTR param);
- static void CALLBACK APC_GetUnitInfo2(ULONG_PTR param);
- static void CALLBACK APC_GetDiscInfoEx(ULONG_PTR param);
- static void CALLBACK APC_GetDiscInfo2(ULONG_PTR param);
- static void CALLBACK APC_GetTitle(ULONG_PTR param);
- static void CALLBACK APC_DriveScan(ULONG_PTR param);
- static void CALLBACK APC_GetMCIInfo(ULONG_PTR param);
- static void CALLBACK APC_GetIMAPIInfo(ULONG_PTR param);
- static void CALLBACK APC_Eject(ULONG_PTR param);
- static DWORD CALLBACK InfoThread(LPVOID param);
- static DWORD CALLBACK PollingThread(LPVOID param);
- static void CALLBACK PollMediumInfo(ULONG_PTR param);
- static LRESULT WINAPI ListenerWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- static CHAR CheckLetter(CHAR cLetter)
- {
- if (cLetter < 'A' || cLetter > 'Z')
- {
- if (cLetter >= 'a' && cLetter <= 'z') return (cLetter - 0x20);
- return 0;
- }
- return cLetter;
- }
- static LPCWSTR GetDeviceName(CHAR cLetter)
- {
- LPCWSTR pszDevName;
- if (!pMngr) return NULL;
- pszDevName = NULL;
- EnterCriticalSection(&pMngr->csLock);
- for (int i = 0; i < pMngr->nCount; i++)
- {
- if (pMngr->pDrives[i].cLetter == cLetter)
- {
- pszDevName = pMngr->pDrives[i].pszDevName;
- break;
- }
- }
- LeaveCriticalSection(&pMngr->csLock);
- return pszDevName;
- }
- static BOOL IsPollingRequired(void)
- {
- HKEY hKey;
- LONG result;
- BOOL bAutoRunEnabled;
- bAutoRunEnabled = FALSE;
- result = RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\Cdrom"), &hKey);
- if (ERROR_SUCCESS == result)
- {
- DWORD value;
- DWORD size;
- size = sizeof(DWORD);
- result = RegQueryValueEx(hKey, TEXT("AutoRun"), NULL, NULL, (LPBYTE)&value, &size);
- if (ERROR_SUCCESS == result) bAutoRunEnabled = (0 != value);
- RegCloseKey(hKey);
- }
- return !bAutoRunEnabled;
- }
- static CHAR Drive_LetterFromMask(ULONG unitmask)
- {
- char i;
- for (i = 0; i < 26; ++i)
- {
- if (unitmask & 0x1) break;
- unitmask = unitmask >> 1;
- }
- return (i + 'A');
- }
- static BOOL Drive_Add(DEVICEINFO *pDevInfo)
- {
- DRIVEINFO_I *pDrive;
- if (!pMngr) return FALSE;
- EnterCriticalSection(&pMngr->csLock);
- INT index, opCode;
- opCode = 0;
- for (index = 0; index < pMngr->nCount && pMngr->pDrives[index].cLetter != pDevInfo->cLetter; index++);
- if (index != pMngr->nCount)
- {
- pDrive = &pMngr->pDrives[index];
- if (pDrive->deviceNumber != pDevInfo->deviceNumber || pDrive->dwType != pDevInfo->dwType) opCode = 1;
- }
- else
- {
- if (pMngr->nCount == pMngr->nAlloc)
- {
- LPVOID data;
- data = realloc(pMngr->pDrives, sizeof(DRIVEINFO_I)*(pMngr->nCount + 2));
- if (!data)
- {
- LeaveCriticalSection(&pMngr->csLock);
- return FALSE;
- }
- pMngr->pDrives = (DRIVEINFO_I*)data;
- pMngr->nAlloc += 2;
- }
- pDrive = &pMngr->pDrives[pMngr->nCount];
- pMngr->nCount++;
- ZeroMemory(pDrive, sizeof(DRIVEINFO_I));
- pDrive->cLetter = pDevInfo->cLetter;
- opCode = 2;
- }
- if (opCode)
- {
- pDrive->deviceNumber = pDevInfo->deviceNumber;
- pDrive->dwType = pDevInfo->dwType;
- if (pDrive->pszDevName) free(pDrive->pszDevName);
- pDrive->pszDevName = _wcsdup(pDevInfo->pszDevName);
- }
- LeaveCriticalSection(&pMngr->csLock);
- if (opCode && pMngr->callback) pMngr->callback((2 == opCode) ? DMW_DRIVEADDED : DMW_DRIVECHANGED, pDevInfo->cLetter);
- return TRUE;
- }
- static BOOL Drive_Remove(CHAR cLetter)
- {
- INT index;
- BOOL bReportChanges;
- if (!pMngr) return FALSE;
- EnterCriticalSection(&pMngr->csLock);
- bReportChanges = FALSE;
- index = pMngr->nCount;
- while (index-- && pMngr->pDrives[index].cLetter != cLetter);
- if (-1 != index)
- {
- if (pMngr->pDrives[index].pszDevName) free(pMngr->pDrives[index].pszDevName);
- if (index != pMngr->nCount - 1) MoveMemory(&pMngr->pDrives[index], &pMngr->pDrives[index + 1], sizeof(DRIVEINFO_I)*(pMngr->nCount - index));
- pMngr->nCount--;
- bReportChanges = TRUE;
- }
- LeaveCriticalSection(&pMngr->csLock);
- if (bReportChanges && pMngr->callback) pMngr->callback(DMW_DRIVEREMOVED, cLetter);
- return TRUE;
- }
- static HRESULT QueueInfoAPC(CHAR cLetter, PAPCFUNC pfnAPC, ULONG_PTR param)
- {
- DWORD *pdwThreadId(NULL);
- HRESULT hr(S_FALSE);
- HANDLE *phThread(NULL);
- static HANDLE hDrivesInfoThread = NULL;
- if (NULL == pMngr) return E_FAIL;
- EnterCriticalSection(&pMngr->csLock);
- if (cLetter)
- {
- INT index = pMngr->nCount;
- while (index-- && pMngr->pDrives[index].cLetter != cLetter);
- if (-1 != index)
- {
- phThread = &pMngr->pDrives[index].hThread;
- pdwThreadId = &pMngr->pDrives[index].dwThreadId;
- }
- }
- else
- {
- phThread = &hDrivesInfoThread;
- }
- if (phThread)
- {
- if (!*phThread)
- {
- DWORD tid;
- *phThread = CreateThread(NULL, 0, InfoThread, NULL, 0, &tid);
- if (pdwThreadId) *pdwThreadId = tid;
- Sleep(100);
- }
- if (*phThread)
- {
- if (0 == QueueUserAPC(pfnAPC, *phThread, param))
- {
- TRACE_LINE(TEXT("queue user apc failed"));
- }
- else hr = S_OK;
- }
- }
- LeaveCriticalSection(&pMngr->csLock);
- return hr;
- }
- static BOOL Medium_Add(CHAR cLetter, DWORD serial)
- {
- INT index;
- if (!pMngr) return FALSE;
- EnterCriticalSection(&pMngr->csLock);
- index = pMngr->nCount;
- while (index-- && pMngr->pDrives[index].cLetter != cLetter);
- if (-1 != index)
- {
- pMngr->pDrives[index].bMediumInserted = TRUE;
- pMngr->pDrives[index].mediumInfo.msLastPolled = 0;
- pMngr->pDrives[index].mediumInfo.serialNumber = serial;
- }
- LeaveCriticalSection(&pMngr->csLock);
- if (-1 != index)
- {
- if (-1 == serial) QueueInfoAPC(cLetter, APC_IsMediumChanged, (ULONG_PTR)cLetter);
- if (pMngr->callback) pMngr->callback(DMW_MEDIUMARRIVED, cLetter);
- }
- return TRUE;
- }
- static BOOL Medium_Remove(CHAR cLetter)
- {
- INT index;
- if (!pMngr) return FALSE;
- EnterCriticalSection(&pMngr->csLock);
- index = pMngr->nCount;
- while (index-- && pMngr->pDrives[index].cLetter != cLetter);
- if (-1 != index) pMngr->pDrives[index].bMediumInserted = FALSE;
- LeaveCriticalSection(&pMngr->csLock);
- if (-1 != index && pMngr->callback) pMngr->callback(DMW_MEDIUMREMOVED, cLetter);
- return TRUE;
- }
- BOOL DriveManager_Initialize(DMNPROC DMNProc, BOOL bSuspended)
- {
- WNDCLASSW wc = {0};
- HINSTANCE hInstance;
- if (pMngr || !DMNProc) return FALSE;
- pMngr = (DRIVEMNGR*)calloc(1, sizeof(DRIVEMNGR));
- if (!pMngr) return FALSE;
- hInstance = GetModuleHandle(NULL);
- if (!GetClassInfoW(hInstance, LISTENER_CLASSNAME, &wc))
- {
- wc.hInstance = hInstance;
- wc.lpfnWndProc = ListenerWndProc;
- wc.lpszClassName = LISTENER_CLASSNAME;
- if (!RegisterClassW(&wc))
- {
- DriveManager_Uninitialize(0);
- return FALSE;
- }
- }
- pMngr->hwndListener = CreateWindowW(LISTENER_CLASSNAME, LISTENER_WINDOWNAME, WS_DISABLED, 0,0,0,0, HWND_DESKTOP, NULL, hInstance, 0L);
- if (!pMngr->hwndListener)
- {
- DriveManager_Uninitialize(0);
- return FALSE;
- }
- InitializeCriticalSection(&pMngr->csLock);
- pMngr->callback = DMNProc;
- return TRUE;
- }
- BOOL DriveManager_Uninitialize(INT msExitWaitTime)
- {
- if (pMngr)
- {
- WNDCLASSW wc;
- HINSTANCE hInstance;
- if (pMngr->hwndListener) DestroyWindow(pMngr->hwndListener);
- hInstance = GetModuleHandle(NULL);
- if (GetClassInfoW(hInstance, LISTENER_CLASSNAME, &wc)) UnregisterClassW(LISTENER_CLASSNAME, hInstance);
- EnterCriticalSection(&pMngr->csLock);
- for (int index =0; index < pMngr->nCount; index++)
- {
- if (pMngr->pDrives[index].hThread)
- {
- PostThreadMessage(pMngr->pDrives[index].dwThreadId, WM_EX_QUIT, 1, 0);
- INT result = WaitForSingleObject(pMngr->pDrives[index].hThread, msExitWaitTime);
- if (WAIT_TIMEOUT == result) TerminateThread(pMngr->pDrives[index].hThread, 1);
- CloseHandle(pMngr->pDrives[index].hThread);
- pMngr->pDrives[index].hThread = NULL;
- }
- }
- LeaveCriticalSection(&pMngr->csLock);
- if (pMngr->hPollingThread)
- {
- PostThreadMessage(pMngr->dwPollingThread, WM_EX_QUIT, 1, 0);
- INT result = WaitForSingleObject(pMngr->hPollingThread, msExitWaitTime);
- if (WAIT_TIMEOUT == result) TerminateThread(pMngr->hPollingThread, 1);
- CloseHandle(pMngr->hPollingThread);
- pMngr->hPollingThread = NULL;
- }
- EnterCriticalSection(&pMngr->csLock);
- if (pMngr->pDrives)
- {
- free(pMngr->pDrives);
- }
- DRIVEMNGR *managerInstance = pMngr;
- pMngr = NULL;
- LeaveCriticalSection(&managerInstance->csLock);
- DeleteCriticalSection(&managerInstance->csLock);
- free(managerInstance);
- PrimoSDKHelper_Uninitialize();
- }
- return TRUE;
- }
- BOOL DriveManager_Suspend(void)
- {
- if (!pMngr) return FALSE;
- pMngr->fState = DMS_SUSPENDED;
- if (pMngr->hPollingThread)
- {
- PostThreadMessage(pMngr->dwPollingThread, WM_EX_QUIT, 1, 0);
- pMngr->hPollingThread = NULL;
- }
- return TRUE;
- }
- BOOL DriveManager_Update(BOOL bAsync)
- {
- if (bAsync) return (QueueInfoAPC(0, APC_DriveScan, 0) && QueueInfoAPC(0, PollMediumInfo, 0));
- else
- {
- APC_DriveScan(0);
- QueueInfoAPC(0, PollMediumInfo, 0);
- }
- return TRUE;
- }
- BOOL DriveManager_Resume(BOOL bUpdate)
- {
- if (!pMngr) return FALSE;
- pMngr->fState = DMS_ACTIVE;
- EnterCriticalSection(&pMngr->csLock);
- for (int index =0; index < pMngr->nCount; index++) pMngr->pDrives[index].mediumInfo.msLastPolled = 0;
- LeaveCriticalSection(&pMngr->csLock);
- APC_DriveScan(0);
- QueueInfoAPC(0, PollMediumInfo, 0);
- if (NULL == pMngr->hPollingThread && IsPollingRequired())
- {
- pMngr->hPollingThread = CreateThread(NULL, 0, PollingThread, NULL, 0, &pMngr->dwPollingThread);
- }
- return TRUE;
- }
- BOOL DriveManager_SetDriveMode(CHAR cLetter, CHAR cMode)
- {
- BOOL report;
- INT index;
- index = -1;
- report = FALSE;
- cLetter = CheckLetter(cLetter);
- if (pMngr && cLetter)
- {
- EnterCriticalSection(&pMngr->csLock);
- for (index =0; index < pMngr->nCount; index++)
- {
- if (pMngr->pDrives[index].cLetter == cLetter)
- {
- if (pMngr->pDrives[index].cMode != cMode)
- {
- pMngr->pDrives[index].cMode = cMode;
- report = TRUE;
- }
- break;
- }
- }
- if (index == pMngr->nCount) index = -1;
- LeaveCriticalSection(&pMngr->csLock);
- if (report && pMngr->callback) pMngr->callback(DMW_MODECHANGED, MAKEWORD(cLetter, cMode));
- }
- return (-1 != index);
- }
- CHAR DriveManager_GetDriveMode(CHAR cLetter)
- {
- CHAR result;
- result = DM_MODE_ERROR;
- cLetter = CheckLetter(cLetter);
- if (pMngr && cLetter)
- {
- INT index;
- EnterCriticalSection(&pMngr->csLock);
- for (index =0; index < pMngr->nCount; index++)
- {
- if (pMngr->pDrives[index].cLetter == cLetter)
- {
- result = pMngr->pDrives[index].cMode;
- break;
- }
- }
- LeaveCriticalSection(&pMngr->csLock);
- }
- return result;
- }
- DWORD DriveManager_GetDriveType(CHAR cLetter)
- {
- DWORD type;
- type = DRIVE_TYPE_UNKNOWN | DRIVE_CAP_UNKNOWN;
- cLetter = CheckLetter(cLetter);
- if (pMngr && cLetter)
- {
- INT index;
- EnterCriticalSection(&pMngr->csLock);
- for (index =0; index < pMngr->nCount; index++)
- {
- if (pMngr->pDrives[index].cLetter == cLetter)
- {
- type = pMngr->pDrives[index].dwType;
- break;
- }
- }
- LeaveCriticalSection(&pMngr->csLock);
- }
- return type;
- }
- BOOL DriveManager_IsMediumInserted(CHAR cLetter)
- {
- BOOL result;
- result = FALSE;
- cLetter = CheckLetter(cLetter);
- if (pMngr && cLetter)
- {
- INT index;
- EnterCriticalSection(&pMngr->csLock);
- for (index =0; index < pMngr->nCount; index++)
- {
- if (pMngr->pDrives[index].cLetter == cLetter)
- {
- result = pMngr->pDrives[index].bMediumInserted;
- break;
- }
- }
- LeaveCriticalSection(&pMngr->csLock);
- }
- return result;
- }
- INT DriveManager_GetDriveList(CHAR *pLetters, INT cchSize)
- {
- INT r = 0;
- if (!pLetters || !pMngr) return -1;
- EnterCriticalSection(&pMngr->csLock);
- for (int index =0; index < pMngr->nCount; index++)
- {
- *pLetters = pMngr->pDrives[index].cLetter;
- pLetters++;
- cchSize--;
- r++;
- if (0 == cchSize) break;
- }
- LeaveCriticalSection(&pMngr->csLock);
- return r;
- }
- static BOOL QueueInfoJob(PAPCFUNC pfnAPC, DM_NOTIFY_PARAM *pHeader)
- {
- BOOL result(TRUE);
- if (!pMngr || !pHeader) result = FALSE;
- if (result)
- {
- HANDLE hProc = GetCurrentProcess();
- pHeader->hReserved = 0;
- result = (BOOL)DuplicateHandle(hProc, GetCurrentThread(), hProc, &pHeader->hReserved,
- 0, FALSE, DUPLICATE_SAME_ACCESS);
- if (!result) pHeader->hReserved = 0;
- }
- if (result)
- {
- CHAR cLetter = CheckLetter(pHeader->cLetter);
- result = (cLetter && S_OK == QueueInfoAPC(cLetter, pfnAPC, (ULONG_PTR)pHeader));
- }
- if(!result && pHeader && pHeader->fnFree)
- {
- if (pHeader->hReserved) CloseHandle(pHeader->hReserved);
- pHeader->fnFree(pHeader);
- }
- return result;
- }
- BOOL DriveManager_GetUnitInfo(DM_UNITINFO_PARAM *puip)
- {
- return QueueInfoJob(APC_GetUnitInfo, (DM_NOTIFY_PARAM*)puip);
- }
- BOOL DriveManager_GetUnitInfo2(DM_UNITINFO2_PARAM *puip)
- {
- return QueueInfoJob(APC_GetUnitInfo2, (DM_NOTIFY_PARAM*)puip);
- }
- BOOL DriveManager_GetDiscInfoEx(DM_DISCINFOEX_PARAM *pdip)
- {
- return QueueInfoJob(APC_GetDiscInfoEx, (DM_NOTIFY_PARAM*)pdip);
- }
- BOOL DriveManager_GetDiscInfo2(DM_DISCINFO2_PARAM *pdip)
- {
- return QueueInfoJob(APC_GetDiscInfo2, (DM_NOTIFY_PARAM*)pdip);
- }
- BOOL DriveManager_QueryTitle(DM_TITLE_PARAM *pdtp)
- {
- return QueueInfoJob(APC_GetTitle, (DM_NOTIFY_PARAM*)pdtp);
- }
- BOOL DriveManager_GetMCIInfo(DM_MCI_PARAM *pmcip)
- {
- return QueueInfoJob(APC_GetMCIInfo, (DM_NOTIFY_PARAM*)pmcip);
- }
- BOOL DriveManager_GetIMAPIInfo(DM_IMAPI_PARAM *pIMAPI)
- {
- return QueueInfoJob(APC_GetIMAPIInfo, (DM_NOTIFY_PARAM*)pIMAPI);
- }
- BOOL DriveManager_Eject(CHAR cLetter, INT nCmd)
- {
- if (!pMngr) return FALSE;
- CHAR cLetter1 = CheckLetter(cLetter);
- return (cLetter1 && QueueInfoAPC(cLetter1, APC_Eject, (ULONG_PTR)MAKELONG(cLetter, nCmd)));
- }
- BOOL DriveManager_IsUnitReady(CHAR cLetter, BOOL *pbReady)
- {
- BYTE sc, asc, ascq;
- BOOL bSuccess;
- HANDLE hDevice;
- *pbReady = FALSE;
- hDevice = CreateFileW(GetDeviceName(cLetter), GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
- if (INVALID_HANDLE_VALUE == hDevice) return FALSE;
- bSuccess = SPTI_TestUnitReady(hDevice, &sc, &asc, &ascq, 3);
- if (!bSuccess)
- {
- if (ERROR_SEM_TIMEOUT == GetLastError()) bSuccess = TRUE;
- }
- else if (0x00 == sc || (0x02 == sc && 0x3A == asc)) *pbReady = TRUE;
- CloseHandle(hDevice);
- return bSuccess;
- }
- static BOOL GetVolumeNameForVolumeMountPoint_DL(LPCWSTR lpszVolumeMountPoint, LPWSTR lpszVolumeName, DWORD cchBufferLength)
- {
- static BOOL (WINAPI *func)(LPCWSTR, LPWSTR, DWORD) = NULL;
- if (!func)
- {
- UINT prevErrorMode;
- HMODULE hModule;
- prevErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
- hModule = LoadLibraryW(L"Kernel32.dll");
- SetErrorMode(prevErrorMode);
- if (hModule)
- {
- func = (BOOL (WINAPI*)(LPCWSTR, LPWSTR, DWORD))GetProcAddress(hModule, "GetVolumeNameForVolumeMountPointW");
- FreeLibrary(hModule);
- }
- }
- return (func) ? func(lpszVolumeMountPoint, lpszVolumeName, cchBufferLength) : FALSE;
- }
- static DWORD GetDeviceNames(DEVICEINFO *pDevInfo, INT count)
- {
- HANDLE hDevInfo;
- SP_DEVICE_INTERFACE_DATA spiData;
- SP_DEVICE_INTERFACE_DETAIL_DATA_W *pspiDetailData;
- DWORD dwErrorCode, dwReqSize, dwDetailSize;
- wchar_t volume[128], szDosName[] = L"X:\\", szDosName1[] = L"X:\\";
- if (!pDevInfo || !count) return ERROR_INVALID_DATA;
- for (int i = 0; i < count; i++)
- {
- szDosName[0] = pDevInfo[i].cLetter;
- GetVolumeNameForVolumeMountPoint_DL(szDosName, pDevInfo[i].szVolumeName, sizeof(pDevInfo[i].szVolumeName)/sizeof(wchar_t));
- szDosName1[0] = pDevInfo[i].cLetter;
- QueryDosDeviceW(szDosName1, pDevInfo[i].szTargetPath, sizeof(pDevInfo[i].szTargetPath)/sizeof(wchar_t));
- }
- hDevInfo = SetupDiGetClassDevs((LPGUID)&CdRomClassGuid, NULL, NULL, (DIGCF_PRESENT | DIGCF_INTERFACEDEVICE));
- if (INVALID_HANDLE_VALUE == hDevInfo) return GetLastError();
- dwDetailSize = 0;
- pspiDetailData = NULL;
- spiData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
- dwErrorCode = 0;
- for (int index = 0; !dwErrorCode; index++)
- {
- BOOL bResult = SetupDiEnumDeviceInterfaces(hDevInfo, 0, (LPGUID)&CdRomClassGuid, index, &spiData);
- if (!bResult)
- {
- dwErrorCode = GetLastError();
- break;
- }
- bResult = SetupDiGetDeviceInterfaceDetailW(hDevInfo, &spiData, NULL, 0, &dwReqSize, NULL);
- if (!bResult)
- {
- dwErrorCode = GetLastError();
- if (ERROR_INSUFFICIENT_BUFFER != dwErrorCode) break;
- dwErrorCode = 0;
- }
- dwReqSize += 2*sizeof(wchar_t);
- if (dwReqSize > dwDetailSize)
- {
- LPVOID data;
- data = realloc(pspiDetailData, dwReqSize);
- if (!data) { dwErrorCode = ERROR_NOT_ENOUGH_MEMORY; break; }
- pspiDetailData = (SP_DEVICE_INTERFACE_DETAIL_DATA*)data;
- dwDetailSize = dwReqSize;
- }
- pspiDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
- bResult = SetupDiGetDeviceInterfaceDetailW(hDevInfo, &spiData, pspiDetailData, dwDetailSize, NULL, NULL);
- if (!bResult)
- {
- dwErrorCode = GetLastError();
- break;
- }
- INT cchName;
- cchName = lstrlenW(pspiDetailData->DevicePath);
- pspiDetailData->DevicePath[cchName] = L'\\';
- pspiDetailData->DevicePath[cchName + 1] = 0x00;
- if(GetVolumeNameForVolumeMountPoint_DL(pspiDetailData->DevicePath, volume, sizeof(volume)/sizeof(wchar_t)))
- {
- for (int i = 0; i < count; i++)
- {
- if (!pDevInfo[i].pszDevName && 0 == lstrcmpW(volume, pDevInfo[i].szVolumeName))
- {
- pDevInfo[i].pszDevName = (LPWSTR)calloc((cchName + 1), sizeof(wchar_t));
- if (pDevInfo[i].pszDevName) StringCchCopyNW(pDevInfo[i].pszDevName, cchName + 1, pspiDetailData->DevicePath, cchName);
- break;
- }
- }
- }
- }
- if (pspiDetailData) free(pspiDetailData);
- SetupDiDestroyDeviceInfoList(hDevInfo);
- for (int i = 0; i < count; i++)
- {
- if (!pDevInfo[i].pszDevName)
- {
- wchar_t szDevName[] = L"\\\\.\\x:";
- szDevName[4] = pDevInfo[i].cLetter;
- pDevInfo[i].pszDevName = (LPWSTR)calloc(sizeof(szDevName) + 2, sizeof(wchar_t));
- if (pDevInfo[i].pszDevName) StringCbCopyW(pDevInfo[i].pszDevName, sizeof(szDevName) + 2, szDevName);
- }
- }
- return dwErrorCode;
- }
- static void GetDeviceCaps(DEVICEINFO *pDevInfo, INT count)
- {
- for( int i = 0; i < count; i++)
- {
- pDevInfo[i].dwType = ((pDevInfo[i].dwType & 0x0000FFFF) | DRIVE_CAP_UNKNOWN);
- }
- // TODO come back to this later on, but for the moment not seeing any noticeable issues
- // with disabling this and instead and instead it helps prevent random trk****.tmp
- // files being generated and also seems to fix the crash on start people have here
- /*IDiscMaster *pdm;
- IDiscRecorder *pdr;
- IEnumDiscRecorders *per;
- ULONG nActual;
- HRESULT hr = CoCreateInstance(CLSID_MSDiscMasterObj, NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, IID_IDiscMaster, (void**)&pdm);
- if (SUCCEEDED(hr))
- {
- // TODO determine why this is causing trk*.tmp files to be created when called
- // which ends up spamming the %temp% folder everytime Winamp starts :o(
- hr = pdm->Open();
- if (SUCCEEDED(hr))
- {
- IEnumDiscMasterFormats *pef;
- hr = pdm->EnumDiscMasterFormats(&pef);
- if (SUCCEEDED(hr))
- {
- IID pFormats[2];
- hr = pef->Next(sizeof(pFormats)/sizeof(IID), pFormats, &nActual);
- if (SUCCEEDED(hr))
- {
- while(nActual--) { if (IID_IRedbookDiscMaster == pFormats[nActual]) break; }
- if (nActual != ((ULONG)-1))
- {
- IRedbookDiscMaster *pdf;
- hr = pdm->SetActiveDiscMasterFormat(IID_IRedbookDiscMaster, (void**)&pdf);
- if (SUCCEEDED(hr))
- {
- pdf->Release();
- hr = pdm->EnumDiscRecorders(&per);
- if (SUCCEEDED(hr))
- {
- while (S_OK== per->Next(1, &pdr, &nActual) && nActual > 0)
- {
- BSTR bstrPath;
- hr = pdr->GetPath(&bstrPath);
- if (SUCCEEDED(hr))
- {
- for (int i = 0; i < count; i++)
- {
- if (0 == lstrcmpW(pDevInfo[i].szTargetPath, bstrPath))
- {
- LONG type;
- if (SUCCEEDED(pdr->GetRecorderType(&type)))
- {
- pDevInfo[i].dwType &= 0x0000FFFF;
- switch(type)
- {
- case RECORDER_CDR: pDevInfo[i].dwType |= DRIVE_CAP_R; break;
- case RECORDER_CDRW: pDevInfo[i].dwType |= DRIVE_CAP_RW; break;
- }
- }
- break;
- }
- }
- if (bstrPath) SysFreeString(bstrPath);
- }
- pdr->Release();
- }
- per->Release();
- }
- }
- }
- }
- pef->Release();
- }
- pdm->Close();
- }
- pdm->Release();
- }
- else
- {
- }*/
- }
- static void Listener_OnDeviceChange(HWND hwnd, UINT nType, DWORD_PTR dwData)
- {
- DEV_BROADCAST_HDR *phdr;
- switch(nType)
- {
- case DBT_DEVICEARRIVAL:
- phdr = (DEV_BROADCAST_HDR*)dwData;
- if (DBT_DEVTYP_VOLUME == phdr->dbch_devicetype)
- {
- DEV_BROADCAST_VOLUME *pvol = (DEV_BROADCAST_VOLUME*)phdr;
- if (DBTF_MEDIA == pvol->dbcv_flags) Medium_Add(Drive_LetterFromMask(pvol->dbcv_unitmask), (DWORD)-1);
- else if (0 == pvol->dbcv_flags)
- {
- char root[] = "X:\\";
- root[0] = Drive_LetterFromMask(pvol->dbcv_unitmask);
- if (DRIVE_CDROM == GetDriveTypeA(root)) QueueInfoAPC(0, APC_CheckDrives, (ULONG_PTR)root[0]);
- }
- }
- break;
- case DBT_DEVICEREMOVECOMPLETE:
- phdr = (DEV_BROADCAST_HDR*)dwData;
- if (DBT_DEVTYP_VOLUME == phdr->dbch_devicetype)
- {
- DEV_BROADCAST_VOLUME *pvol = (DEV_BROADCAST_VOLUME*)phdr;
- if (DBTF_MEDIA == pvol->dbcv_flags) Medium_Remove(Drive_LetterFromMask(pvol->dbcv_unitmask));
- else if (0 == pvol->dbcv_flags)
- {
- char root[] = "X:\\";
- root[0] = Drive_LetterFromMask(pvol->dbcv_unitmask);
- if (DRIVE_CDROM == GetDriveTypeA(root)) Drive_Remove(root[0]);
- }
- }
- break;
- }
- }
- static DWORD CALLBACK InfoThread(LPVOID param)
- {
- MSG msg;
- DWORD start, status, timeout, result(0);
- BOOL bComInit, run(TRUE);
- HANDLE hTemp(NULL);
- SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
- bComInit = ( S_OK == CoInitializeEx(NULL, COINIT_APARTMENTTHREADED));
- timeout = 20000; // 20 seconds delay
- start = GetTickCount();
- while(run)
- {
- DWORD elapsed = GetTickCount() - start;
- if (elapsed < timeout)
- status = MsgWaitForMultipleObjectsEx(0, NULL, timeout - elapsed,
- QS_ALLINPUT, MWMO_WAITALL | MWMO_ALERTABLE | MWMO_INPUTAVAILABLE);
- else status = WAIT_TIMEOUT;
- switch(status)
- {
- case WAIT_FAILED:
- if (bComInit) CoUninitialize();
- return (DWORD)-1;
- case WAIT_TIMEOUT:
- if (NULL != pMngr)
- {
- EnterCriticalSection(&pMngr->csLock);
- start = GetCurrentThreadId();
- hTemp = NULL;
-
- for (int i = pMngr->nCount - 1; i >= 0; i--)
- {
- if (pMngr->pDrives[i].dwThreadId == start)
- {
- pMngr->pDrives[i].dwThreadId = 0;
- hTemp = pMngr->pDrives[i].hThread;
- pMngr->pDrives[i].hThread = NULL;
- }
- }
- LeaveCriticalSection(&pMngr->csLock);
- //while (WAIT_IO_COMPLETION == WaitForMultipleObjectsEx(0, NULL, TRUE, 0, TRUE));
- while (SleepEx(0, TRUE) == WAIT_IO_COMPLETION);
- }
- result = 2;
- run = FALSE;
- break;
- case WAIT_IO_COMPLETION: start = GetTickCount(); break;
- case WAIT_OBJECT_0:
- while (run && PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
- {
- switch(msg.message)
- {
- case WM_QUIT:
- result = (DWORD)msg.wParam;
- run = FALSE;
- break;
- case WM_EX_QUIT:
- PostQuitMessage((INT)msg.wParam);
- break;
- default:
- TranslateMessage(&msg);
- DispatchMessageW(&msg);
- break;
- }
- }
- break;
- }
- }
- if (bComInit) CoUninitialize();
- if (2 == result && hTemp) CloseHandle(hTemp);
- hTemp = NULL;
- return result;
- }
- static DWORD CALLBACK PollingThread(LPVOID param)
- {
- MSG msg;
- DWORD status, timeout;
- BOOL bComInit;
- SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_IDLE);
- bComInit = ( S_OK == CoInitializeEx(NULL, COINIT_APARTMENTTHREADED));
- timeout = POLLMEDIUMCHANGE_INTERVAL;
- for(;;)
- {
- DWORD elapsed, start = GetTickCount();
- while ((elapsed = GetTickCount() - start) < timeout)
- {
- status = MsgWaitForMultipleObjectsEx(0, NULL, timeout - elapsed,
- QS_ALLINPUT, MWMO_WAITALL | MWMO_ALERTABLE | MWMO_INPUTAVAILABLE);
- switch(status)
- {
- case WAIT_FAILED:
- if (bComInit) CoUninitialize();
- return (DWORD)-1;
- case WAIT_TIMEOUT: PollMediumInfo(0); break;
- case WAIT_OBJECT_0:
- while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
- {
- switch(msg.message)
- {
- case WM_QUIT:
- if (bComInit) CoUninitialize();
- return (DWORD)msg.wParam;
- case WM_EX_QUIT:
- PostQuitMessage((INT)msg.wParam);
- break;
- default:
- TranslateMessage(&msg);
- DispatchMessageW(&msg);
- break;
- }
- }
- break;
- }
- }
- }
- }
- static void CALLBACK PollMediumInfo(ULONG_PTR param)
- {
- char letters[32] = {0};
- LPCWSTR pszDevName[32] = {0};
- INT index, count;
- if (!pMngr) return;
- count = 0;
- EnterCriticalSection(&pMngr->csLock);
- for (index =0; index < pMngr->nCount; index++)
- {
- if (DM_MODE_BURNING != pMngr->pDrives[index].cMode && DM_MODE_RIPPING != pMngr->pDrives[index].cMode)
- {
- letters[count] = pMngr->pDrives[index].cLetter;
- pszDevName[count] = pMngr->pDrives[index].pszDevName;
- count++;
- }
- }
-
- LeaveCriticalSection(&pMngr->csLock);
- while(count--)
- {
- HANDLE hDevice = CreateFileW(pszDevName[count], GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
- if (INVALID_HANDLE_VALUE != hDevice)
- {
- BYTE sc, asc, ascq;
- BOOL bReady, bReportChanges, bNeedRecheck;
- DWORD ticks;
- bReportChanges = FALSE;
- bNeedRecheck = FALSE;
- if(!SPTI_TestUnitReady(hDevice, &sc, &asc, &ascq, 2))
- {
- bReady = FALSE;
- }
- else bReady = (0x00 == sc || (0x02 == sc && 0x3A == asc));
- CloseHandle(hDevice);
- EnterCriticalSection(&pMngr->csLock);
- for (index =0; index < pMngr->nCount; index++)
- {
- if (pMngr->pDrives[index].cLetter == letters[count])
- {
- ticks = GetTickCount();
- if (pMngr->pDrives[index].bMediumInserted &&
- (ticks - pMngr->pDrives[index].mediumInfo.msLastPolled) > POLLMEDIUMVALIDATE_INTERVAL) bNeedRecheck = TRUE;
- pMngr->pDrives[index].mediumInfo.msLastPolled = ticks;
- if (bReady && ((0x00 == sc) != pMngr->pDrives[index].bMediumInserted)) bReportChanges = TRUE;
- break;
- }
- }
- LeaveCriticalSection(&pMngr->csLock);
- if (bReportChanges)
- {
- if (0 == sc) Medium_Add(letters[count], (DWORD)-1);
- else Medium_Remove(letters[count]);
- }
- else if (bNeedRecheck)
- {
- QueueInfoAPC(letters[count], APC_IsMediumChanged, (DWORD_PTR)letters[count]);
- }
- }
- }
- }
- static LRESULT WINAPI ListenerWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- switch(uMsg)
- {
- case WM_DEVICECHANGE:
- Listener_OnDeviceChange(hwnd, (UINT)wParam, (DWORD_PTR)lParam);
- break;
- }
- return DefWindowProcW(hwnd, uMsg, wParam, lParam);
- }
- static void CALLBACK APC_CheckDrives(ULONG_PTR param)
- {
- INT index, result, count;
- DWORD unitmask, dwOutput;
- STORAGE_DEVICE_NUMBER sdn;
- DEVICEINFO *pDevInfo;
- BYTE buffer[4096] = {0};
- if (!pMngr) return;
- unitmask = (DWORD)param;
- count = 0;
- for (int i = 0; i < 26; i++) {if (0x1 & (unitmask >> i)) count++;}
- if (!count) return;
- pDevInfo = (DEVICEINFO*)calloc(count, sizeof(DEVICEINFO));
- if (!pDevInfo) return;
- index = 0;
- for (int i = 0; i < 26; i++)
- {
- if (0x1 & unitmask)
- {
- pDevInfo[index].cLetter = (CHAR)(('A' + i));
- index++;
- if (index == count) break;
- }
- unitmask = unitmask >> 1;
- }
- GetDeviceNames(pDevInfo, count);
- for (int i = 0; i < count; i++)
- {
- HANDLE hDevice = CreateFileW(pDevInfo[i].pszDevName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
- if (INVALID_HANDLE_VALUE != hDevice)
- {
- ZeroMemory(&sdn, sizeof(STORAGE_DEVICE_NUMBER));
- result = DeviceIoControl(hDevice, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(STORAGE_DEVICE_NUMBER), &dwOutput, NULL);
- pDevInfo->deviceNumber = (result) ? sdn.DeviceNumber : -1;
- ZeroMemory(&buffer, sizeof(buffer)/sizeof(BYTE));
- result = DeviceIoControl(hDevice, IOCTL_STORAGE_GET_MEDIA_TYPES_EX, NULL, 0, buffer, sizeof(buffer)/sizeof(BYTE), &dwOutput, NULL);
- if (result && buffer && (FILE_DEVICE_DVD & ((GET_MEDIA_TYPES*)buffer)->DeviceType)) pDevInfo[i].dwType = DRIVE_TYPE_DVD;
- else pDevInfo[i].dwType = DRIVE_TYPE_CD;
- CloseHandle(hDevice);
- }
- }
- GetDeviceCaps(pDevInfo, count);
- EnterCriticalSection(&pMngr->csLock);
- for (int i = 0; i < count; i++)
- {
- pDevInfo[i].opCode = 0;
- for (index =0; index < pMngr->nCount; index++)
- {
- if (pMngr->pDrives[index].cLetter == pDevInfo[i].cLetter)
- {
- if (-1 == pMngr->pDrives[index].deviceNumber || pMngr->pDrives[index].deviceNumber != pDevInfo[i].deviceNumber)
- pDevInfo[i].opCode = 1;
- break;
- }
- }
- if (pMngr->nCount == index) pDevInfo[i].opCode = 2;
- }
- LeaveCriticalSection(&pMngr->csLock);
- for (int i = 0; i < count; i++)
- {
- if (pDevInfo[i].opCode) Drive_Add(&pDevInfo[i]);
- }
- if (pDevInfo)
- {
- for (int i = 0; i<count; i++)
- {
- if (pDevInfo[i].pszDevName) free(pDevInfo[i].pszDevName);
- }
- free(pDevInfo);
- }
- }
- static void CALLBACK APC_IsMediumChanged(ULONG_PTR param)
- {
- INT opCode;
- DWORD serial;
- wchar_t devname[4] = L"X:\\";
- if (!pMngr) return;
- opCode = 0;
- devname[0] = (char)(0xFF & param);
- if (devname[0])
- {
- BOOL result;
- serial = 0;
- result = GetVolumeInformationW(devname, NULL, 0, &serial, NULL, NULL, NULL, 0);
- if (!result) serial = 0; // perhaps this is empty recordable disc
- EnterCriticalSection(&pMngr->csLock);
- for (INT index =0; index < pMngr->nCount; index++)
- {
- if (pMngr->pDrives[index].cLetter == (char)param )
- {
- pMngr->pDrives[index].mediumInfo.msLastPolled = GetTickCount();
- if (!pMngr->pDrives[index].bMediumInserted && result) opCode = 0x02;
- else if (pMngr->pDrives[index].mediumInfo.serialNumber != serial)
- {
- if (-1 == pMngr->pDrives[index].mediumInfo.serialNumber) pMngr->pDrives[index].mediumInfo.serialNumber = serial;
- else opCode = 0x03;
- }
- break;
- }
- }
- LeaveCriticalSection(&pMngr->csLock);
- if (0x01 & opCode) Medium_Remove((char)param);
- if (0x02 & opCode) Medium_Add((char)param, serial);
- }
- }
- static void CALLBACK APC_AsyncOp_Complete(ULONG_PTR param)
- {
- DM_NOTIFY_PARAM *phdr = (DM_NOTIFY_PARAM*)param;
- if (phdr->hReserved)
- {
- CloseHandle(phdr->hReserved);
- phdr->hReserved = NULL;
- }
- if (phdr->callback)
- {
- if (phdr->uMsg)
- {
- if (IsWindow((HWND)phdr->callback)) SendMessageW((HWND)phdr->callback, phdr->uMsg, (WPARAM)DMW_OPCOMPLETED, (LPARAM)phdr);
- }
- else ((DMNPROC)phdr->callback)(DMW_OPCOMPLETED, (INT_PTR)param);
- }
- if (phdr->fnFree)
- {
- phdr->fnFree(phdr);
- }
- }
- static void AsycOp_Complete(DM_NOTIFY_PARAM *param)
- {
- if (param) QueueUserAPC(APC_AsyncOp_Complete, param->hReserved, (ULONG_PTR)param);
- }
- static void CALLBACK APC_GetUnitInfo(ULONG_PTR param)
- {
- DWORD unit;
- DM_UNITINFO_PARAM *puip;
- puip = (DM_UNITINFO_PARAM*)param;
-
- puip->header.opCode = DMOP_UNITINFO;
-
- unit = CheckLetter(puip->header.cLetter);
-
- if (!unit || (!PrimoSDKHelper_IsInitialized() && !PrimoSDKHelper_Initialize())) puip->header.result = PRIMOSDK_CMDSEQUENCE;
- else
- {
- DWORD ready = 0;
- CHAR buffer[512] = {0};
- puip->header.result = PrimoSDKHelper_UnitInfo(&unit, &puip->dwType,
- ((DMF_DESCRIPTION & puip->header.fFlags) || (DMF_FIRMWARE & puip->header.fFlags)) ? (BYTE*)buffer: NULL,
- (DMF_READY & puip->header.fFlags) ? &ready : NULL);
- if (PRIMOSDK_OK == puip->header.result)
- {
- if (DMF_READY & puip->header.fFlags) puip->bReady = (0 != ready);
- if (DMF_DESCRIPTION & puip->header.fFlags)
- {
- INT len = lstrlenA(buffer);
- if (len > 5) len -= 5;
- if (!puip->pszDesc || puip->cchDesc < (len + 1)) puip->cchDesc = -(len + 1);
- else
- {
- StringCchCopyNA(puip->pszDesc, puip->cchDesc, buffer, len);
- puip->cchDesc = len;
- }
- }
- if (DMF_FIRMWARE & puip->header.fFlags)
- {
- LPSTR p;
- INT len = lstrlenA(buffer);
- p = buffer + (len - ((len > 5) ? 4 : 0));
- if (!puip->pszFirmware || puip->cchFirmware < 4) puip->cchFirmware = -4;
- else
- {
- StringCchCopyA(puip->pszFirmware, puip->cchFirmware, p);
- puip->cchFirmware = 4;
- }
- }
- }
- }
- AsycOp_Complete(&puip->header);
- }
- static void CALLBACK APC_GetUnitInfo2(ULONG_PTR param)
- {
- DWORD unit;
- DM_UNITINFO2_PARAM *puip;
- puip = (DM_UNITINFO2_PARAM*)param;
- puip->header.opCode = DMOP_UNITINFO2;
- unit = CheckLetter(puip->header.cLetter);
- if (!unit || (!PrimoSDKHelper_IsInitialized() && !PrimoSDKHelper_Initialize())) puip->header.result = PRIMOSDK_CMDSEQUENCE;
- else
- {
- BOOL bReady;
- DWORD szTypes[32], rfu;
- if (DriveManager_IsUnitReady((char)unit, &bReady) && !bReady)
- {
- SleepEx(1000, TRUE);
- QueueUserAPC(APC_GetUnitInfo2, GetCurrentThread(), param);
- return;
- }
- puip->header.result = PrimoSDKHelper_UnitInfo2(&unit, szTypes, &puip->dwClassId, &puip->dwBusType, &rfu);
- if (PRIMOSDK_OK == puip->header.result)
- {
- if (DMF_TYPES & puip->header.fFlags)
- {
- INT len;
- for (len = 0; szTypes[len] != 0xFFFFFFFF; len++);
-
- if (!puip->pdwTypes || puip->nTypes < len) puip->nTypes = -len;
- else
- {
- puip->nTypes = len;
- if (len) CopyMemory(puip->pdwTypes, szTypes, sizeof(DWORD)*len);
- }
- }
- }
- }
- AsycOp_Complete(&puip->header);
- }
- static void CALLBACK APC_GetDiscInfoEx(ULONG_PTR param)
- {
- DWORD unit;
- DM_DISCINFOEX_PARAM *pdip;
- pdip = (DM_DISCINFOEX_PARAM*)param;
- pdip->header.opCode = DMOP_DISCINFO;
- unit = CheckLetter(pdip->header.cLetter);
- if (!unit || (!PrimoSDKHelper_IsInitialized() && !PrimoSDKHelper_Initialize())) pdip->header.result = PRIMOSDK_CMDSEQUENCE;
- else
- {
- BOOL bReady;
- DWORD dwFlags, dwErasable;
- if (DriveManager_IsUnitReady((char)unit, &bReady) && !bReady)
- {
- SleepEx(1000, TRUE);
- QueueUserAPC(APC_GetDiscInfoEx, GetCurrentThread(), param);
- return;
- }
- dwFlags = (DMF_DRIVEMODE_TAO & pdip->header.fFlags);
- pdip->header.result = PrimoSDKHelper_DiscInfoEx(&unit, dwFlags,
- (DMF_MEDIUMTYPE & pdip->header.fFlags) ? &pdip->dwMediumType : NULL,
- (DMF_MEDIUMFORMAT & pdip->header.fFlags) ? &pdip->dwMediumFormat : NULL,
- &dwErasable,
- (DMF_TRACKS & pdip->header.fFlags) ? &pdip->dwTracks: NULL,
- (DMF_USED & pdip->header.fFlags) ? &pdip->dwUsed : NULL,
- (DMF_FREE & pdip->header.fFlags) ? &pdip->dwFree : NULL);
- if (PRIMOSDK_OK == pdip->header.result) pdip->bErasable = (0 != dwErasable);
- }
- AsycOp_Complete(&pdip->header);
- }
- static void CALLBACK APC_GetDiscInfo2(ULONG_PTR param)
- {
- DWORD unit;
- DM_DISCINFO2_PARAM *pdip;
- pdip = (DM_DISCINFO2_PARAM*)param;
- pdip->header.opCode = DMOP_DISCINFO2;
- unit = CheckLetter(pdip->header.cLetter);
- if (!unit || (!PrimoSDKHelper_IsInitialized() && !PrimoSDKHelper_Initialize())) pdip->header.result = PRIMOSDK_CMDSEQUENCE;
- else
- {
- DWORD rfu, medium, protectedDVD, flags;
- BOOL bReady;
- if (DriveManager_IsUnitReady((char)unit, &bReady) && !bReady)
- {
- SleepEx(1000, TRUE);
- QueueUserAPC(APC_GetDiscInfo2, GetCurrentThread(), param);
- return;
- }
- pdip->header.result = PrimoSDKHelper_DiscInfo2(&unit,
- (DMF_MEDIUM & pdip->header.fFlags) ? &pdip->dwMedium : (DMF_MEDIUMEX & pdip->header.fFlags) ? &medium : NULL,
- (DMF_PROTECTEDDVD & pdip->header.fFlags) ? &protectedDVD : NULL,
- (DMF_PACKETWRITTEN & pdip->header.fFlags) ? &flags : NULL,
- (DMF_MEDIUMEX & pdip->header.fFlags) ? &pdip->dwMediumEx : NULL,
- &rfu);
- if (PRIMOSDK_OK == pdip->header.result)
- {
- if (DMF_PROTECTEDDVD & pdip->header.fFlags) pdip->bProtectedDVD = (0 != protectedDVD);
- if (DMF_PACKETWRITTEN & pdip->header.fFlags) pdip->bPacketWritten = (0 != (PRIMOSDK_PACKETWRITTEN & protectedDVD));
- }
- }
- AsycOp_Complete(&pdip->header);
- }
- static void CALLBACK APC_GetTitle(ULONG_PTR param)
- {
- CHAR cLetter;
- DM_TITLE_PARAM *pdtp;
- pdtp = (DM_TITLE_PARAM*)param;
- pdtp->header.opCode = DMOP_TITLE;
- cLetter = CheckLetter(pdtp->header.cLetter);
- pdtp->header.result = PRIMOSDK_CMDSEQUENCE;
- if (cLetter && pdtp->pszTitle)
- {
- wchar_t name[] = L"X:\\";
- MCIDEVICEID devId;
- MCI_OPEN_PARMS op = {0};
- MCI_GENERIC_PARMS gp = {0};
- MCI_STATUS_PARMS sp = {0};
- name[0] = cLetter;
- op.lpstrDeviceType = (LPWSTR)MCI_DEVTYPE_CD_AUDIO;
- op.lpstrElementName = name;
- if (!mciSendCommandW(0, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_SHAREABLE | MCI_OPEN_TYPE_ID | MCI_OPEN_ELEMENT, (DWORD_PTR)&op))
- {
- HRESULT hr;
- devId = op.wDeviceID;
- sp.dwItem = MCI_STATUS_MEDIA_PRESENT;
- INT present = (!mciSendCommandW(devId, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD_PTR)&sp)) ? (BOOL)sp.dwReturn : 0;
- if (present)
- {
- INT nTracks;
- BOOL bAudio;
- wchar_t szVolume[256] = {0};
- // check if we have at least one audio track
- sp.dwItem = MCI_STATUS_NUMBER_OF_TRACKS;
- nTracks = (!mciSendCommandW(devId, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD_PTR)&sp)) ? (INT)sp.dwReturn : -1;
- bAudio = FALSE;
-
- if (nTracks > 0)
- {
- sp.dwItem = MCI_CDA_STATUS_TYPE_TRACK;
- for (sp.dwTrack = 1; sp.dwTrack <= (UINT)nTracks && !bAudio; sp.dwTrack++)
- {
- mciSendCommandW(devId, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD_PTR)&sp);
- bAudio = (MCI_CDA_TRACK_AUDIO == sp.dwReturn);
- }
- if (bAudio) WASABI_API_LNGSTRINGW_BUF(IDS_CD_AUDIO, szVolume, sizeof(szVolume)/sizeof(wchar_t));
- else
- {
- INT result;
- wchar_t devname[4] = L"X:\\";
- devname[0] = cLetter;
- result = GetVolumeInformationW(devname, szVolume, sizeof(szVolume)/sizeof(wchar_t), NULL, NULL, NULL, NULL, 0);
- if (!result) WASABI_API_LNGSTRINGW_BUF(IDS_DISC_DATA, szVolume, sizeof(szVolume)/sizeof(wchar_t));
- }
- }
- else WASABI_API_LNGSTRINGW_BUF(IDS_DISC_BLANK, szVolume, sizeof(szVolume)/sizeof(wchar_t));
- hr = StringCchPrintfW(pdtp->pszTitle, pdtp->cchTitle, L"%s (%c:)", szVolume, cLetter);
- }
- else
- {
- INT nDriveType, nDriveCap;
- DWORD type;
- wchar_t szDriveType[32] = {0}, szDriveCap[64] = {0};
- type = DriveManager_GetDriveType(cLetter);
- if ((DRIVE_TYPE_UNKNOWN | DRIVE_CAP_UNKNOWN) == type) type = DRIVE_TYPE_CD;
- nDriveCap = ((DRIVE_CAP_R | DRIVE_CAP_RW) & type) ? IDS_RECORDER_CAP : IDS_DRIVE_CAP;
- nDriveType = (IDS_DRIVE_CAP == nDriveCap && (DRIVE_TYPE_DVD & type)) ? IDS_DVD : IDS_CD;
- WASABI_API_LNGSTRINGW_BUF(nDriveType, szDriveType, sizeof(szDriveType)/sizeof(wchar_t));
- WASABI_API_LNGSTRINGW_BUF(nDriveCap, szDriveCap, sizeof(szDriveCap)/sizeof(wchar_t));
- hr = StringCchPrintfW(pdtp->pszTitle, pdtp->cchTitle, L"%s %s (%C:)", szDriveType, szDriveCap, cLetter);
- }
- pdtp->header.result = hr;
- mciSendCommandW(devId, MCI_CLOSE, MCI_WAIT, (DWORD_PTR)&gp);
- }
- }
- AsycOp_Complete(&pdtp->header);
- }
- static void CALLBACK APC_DriveScan(ULONG_PTR param)
- {
- char i;
- char root[] = "A:\\";
- DWORD unitmask;
- DEVICEINFO di = {0};
- /// detect drives
- unitmask = GetLogicalDrives();
- di.deviceNumber = -1;
- di.dwType = DRIVE_TYPE_CD;
-
- for (i = 0; i < 26; ++i)
- {
- if (0x1 & (unitmask >> i))
- {
- root[0] = ('A' + i);
- if(DRIVE_CDROM != GetDriveTypeA(root)) unitmask &= ~(1 << i);
- else
- {
- di.cLetter = root[0];
- Drive_Add(&di);
- }
- }
- }
- APC_CheckDrives((ULONG_PTR)unitmask);
- }
- #define MAX_TEST_ATTEMPT 20
- static void CALLBACK APC_Eject(ULONG_PTR param)
- {
- INT nCmd;
- CHAR cLetter;
- BYTE sc(0), asc(0), ascq(0);
- nCmd = HIWORD(param);
- cLetter = CheckLetter((CHAR)param);
- if (cLetter && DM_MODE_READY == DriveManager_GetDriveMode(cLetter))
- {
- BOOL bSuccess;
- HANDLE hDevice;
- hDevice = CreateFileW(GetDeviceName(cLetter), GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
- if (INVALID_HANDLE_VALUE != hDevice)
- {
- DWORD dwOutput;
- LARGE_INTEGER start, finish;
-
- bSuccess = SPTI_TestUnitReady(hDevice, &sc, &asc, &ascq, 3);
- if (!bSuccess && ERROR_SEM_TIMEOUT == GetLastError())
- {
- bSuccess = TRUE;
- sc = 0xFF;
- }
-
- if (bSuccess && (0 == sc || (0x02 == sc && 0x3A == asc)))
- {
- INT opCode;
- opCode = (DM_EJECT_REMOVE == nCmd || 0x00 == sc || (0x3A == asc && 0x01 == ascq)) ?
- IOCTL_STORAGE_EJECT_MEDIA : IOCTL_STORAGE_LOAD_MEDIA;
-
- QueryPerformanceCounter(&start);
- bSuccess = DeviceIoControl(hDevice, opCode, NULL, 0, NULL, 0, &dwOutput, NULL);
- QueryPerformanceCounter(&finish);
-
- if (bSuccess && DM_EJECT_CHANGE == nCmd && 0x00 != sc && 0x00 == ascq)
- {
- finish.QuadPart -= start.QuadPart;
- if (finish.QuadPart < freq.QuadPart && (finish.QuadPart*100000 / freq.QuadPart) < 200)
- {
- // test unit redy
- INT i;
- sc = 0x02; asc = 0x04; ascq = 0x01;
- for (i = 0; i < MAX_TEST_ATTEMPT && 0x02 == sc && 0x04 == asc && 0x01 == ascq; i++)
- {
- Sleep(50);
- if (!SPTI_TestUnitReady(hDevice, &sc, &asc, &ascq, 3) && ERROR_SEM_TIMEOUT == GetLastError())
- i = MAX_TEST_ATTEMPT;
- }
- if (i < MAX_TEST_ATTEMPT && 0x02 == sc && 0x3A ==asc)
- {
- DeviceIoControl(hDevice, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, &dwOutput, NULL);
- }
- sc = 0x00;
- }
- }
- }
- CloseHandle(hDevice);
- }
- else bSuccess = FALSE;
- if (!bSuccess)
- { // we can try MCI
- }
- else if (0x00 != sc && !(0x02 == sc && 0x3A == asc))
- {
- SleepEx(200, TRUE);
- QueueUserAPC(APC_Eject, GetCurrentThread(), param);
- return;
- }
- }
- }
- static void CALLBACK APC_GetMCIInfo(ULONG_PTR param)
- {
- CHAR cLetter;
- MCI_OPEN_PARMS op = {0};
- DM_MCI_PARAM *pmcip;
- pmcip = (DM_MCI_PARAM*)param;
- pmcip->header.opCode = DMOP_MCIINFO;
- cLetter = CheckLetter(pmcip->header.cLetter);
- pmcip->header.result = PRIMOSDK_CMDSEQUENCE;
- if (cLetter)
- {
- wchar_t name[] = L"X:\\";
- MCIDEVICEID devId;
- MCI_INFO_PARMS ip = {0};
- MCI_GENERIC_PARMS gp = {0};
- MCI_STATUS_PARMS sp = {0};
- name[0] = cLetter;
- op.lpstrDeviceType = (LPWSTR)MCI_DEVTYPE_CD_AUDIO;
- op.lpstrElementName = name;
- if (!mciSendCommandW(0, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_SHAREABLE | MCI_OPEN_TYPE_ID | MCI_OPEN_ELEMENT, (DWORD_PTR)&op))
- {
- WCHAR buffer[512] = {0};
- INT nMaxTracks = pmcip->nTracks;
- devId = op.wDeviceID;
- if ((DMF_TRACKCOUNT | DMF_TRACKSINFO) & pmcip->header.fFlags)
- {
- sp.dwItem = MCI_STATUS_NUMBER_OF_TRACKS;
- pmcip->nTracks = (!mciSendCommandW(devId, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD_PTR)&sp)) ? (INT)sp.dwReturn : -1;
- }
- if (DMF_READY & pmcip->header.fFlags)
- {
- sp.dwItem = MCI_STATUS_READY;
- pmcip->bReady = (!mciSendCommandW(devId, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD_PTR)&sp)) ? (BOOL)sp.dwReturn : 0;
- }
- if (DMF_MODE & pmcip->header.fFlags)
- {
- sp.dwItem = MCI_STATUS_MODE;
- pmcip->uMode = (!mciSendCommandW(devId, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD_PTR)&sp)) ? (UINT)sp.dwReturn : 0;
- }
- if (DMF_MEDIUMPRESENT & pmcip->header.fFlags)
- {
- sp.dwItem = MCI_STATUS_MEDIA_PRESENT;
- pmcip->bMediumPresent = (!mciSendCommandW(devId, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD_PTR)&sp)) ? (BOOL)sp.dwReturn : 0;
- }
- if (DMF_MEDIUMUID & pmcip->header.fFlags)
- {
- ip.dwRetSize = sizeof(buffer)/sizeof(wchar_t);
- ip.lpstrReturn= buffer;
- if (!mciSendCommandW(devId, MCI_INFO, MCI_WAIT | MCI_INFO_MEDIA_IDENTITY, (DWORD_PTR)&ip))
- {
- INT len;
- len = lstrlenW(ip.lpstrReturn);
- if (S_OK == StringCchCopyW(pmcip->pszMediumUID, pmcip->cchMediumUID, ip.lpstrReturn))
- {
- pmcip->cchMediumUID = len;
- }
- else pmcip->cchMediumUID = 0 - (len + 1);
- }
- else pmcip->cchMediumUID = -1;
- }
- if (DMF_MEDIUMUPC & pmcip->header.fFlags)
- {
- ip.dwCallback = NULL;
- ip.dwRetSize = sizeof(buffer)/sizeof(wchar_t);
- ip.lpstrReturn = buffer;
- if (!mciSendCommandW(devId, MCI_INFO, MCI_WAIT | MCI_INFO_MEDIA_UPC, (DWORD_PTR)&ip))
- {
- INT len;
- len = lstrlenW(ip.lpstrReturn);
- if (S_OK == StringCchCopyW(pmcip->pszMediumUPC, pmcip->cchMediumUPC, ip.lpstrReturn))
- {
- pmcip->cchMediumUPC = len;
- }
- else pmcip->cchMediumUPC = 0 - (len + 1);
- }
- else pmcip->cchMediumUPC = -1;
- }
- if (DMF_TRACKSINFO & pmcip->header.fFlags)
- {
- MCI_SET_PARMS setp;
- if (nMaxTracks < pmcip->nTracks) pmcip->nTracks = (0 - pmcip->nTracks);
- else
- {
- INT prevPos(0), length(0);
- setp.dwTimeFormat = MCI_FORMAT_MILLISECONDS;
- mciSendCommandW(devId, MCI_SET, MCI_WAIT | MCI_SET_TIME_FORMAT, (DWORD_PTR)&setp);
- for (int i = pmcip->nTracks; i > 0; i--)
- {
- sp.dwItem = MCI_CDA_STATUS_TYPE_TRACK;
- sp.dwTrack = i;
- mciSendCommandW(devId, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD_PTR)&sp);
- BOOL bAudio = (MCI_CDA_TRACK_AUDIO == sp.dwReturn);
-
- sp.dwItem = MCI_STATUS_POSITION;
- sp.dwTrack = i;
- mciSendCommandW(devId, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD_PTR)&sp);
-
- if (i != pmcip->nTracks) length = prevPos - (INT)sp.dwReturn;
- prevPos = (INT)sp.dwReturn;
- if (i == pmcip->nTracks)
- {
- sp.dwItem = MCI_STATUS_LENGTH;
- sp.dwTrack = i;
- mciSendCommandW(devId, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD_PTR)&sp);
- length = (INT)sp.dwReturn;
- }
- pmcip->pTracks[i- 1] = (0x7FFFFFF & length) | ((bAudio) ? 0x80000000 : 0);
- }
-
- setp.dwTimeFormat = MCI_FORMAT_TMSF;
- mciSendCommandW(devId, MCI_SET, MCI_WAIT | MCI_SET_TIME_FORMAT, (DWORD_PTR)&setp);
- }
- }
- mciSendCommandW(devId, MCI_CLOSE, MCI_WAIT, (DWORD_PTR)&gp);
- pmcip->header.result = PRIMOSDK_OK;
- }
- }
- AsycOp_Complete(&pmcip->header);
- }
- static void CALLBACK APC_GetIMAPIInfo(ULONG_PTR param)
- {
- CHAR cLetter;
- BOOL bReady;
- HRESULT hr(S_FALSE);
- IDiscMaster *pdm;
- IDiscRecorder *pdr;
- IEnumDiscRecorders *per;
- ULONG nActual;
-
- wchar_t szDevName[] = L"X:\\";
- wchar_t szTargetName[128] = {0};
- DM_IMAPI_PARAM *pIMAPI;
- pIMAPI = (DM_IMAPI_PARAM*)param;
- cLetter = CheckLetter(pIMAPI->header.cLetter);
- if (DriveManager_IsUnitReady(cLetter, &bReady) && !bReady)
- {
- SleepEx(1000, TRUE);
- QueueUserAPC(APC_GetIMAPIInfo, GetCurrentThread(), param);
- return;
- }
-
- pIMAPI->header.opCode = DMOP_IMAPIINFO;
-
- pIMAPI->bRecorder = FALSE;
- pIMAPI->header.result = (DWORD)E_INVALIDARG;
-
- szDevName[0] = cLetter;
- if (cLetter && QueryDosDeviceW(szDevName, szTargetName, sizeof(szTargetName)/sizeof(wchar_t)))
- {
- hr = CoCreateInstance(CLSID_MSDiscMasterObj, NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, IID_IDiscMaster, (void**)&pdm);
- if (SUCCEEDED(hr))
- {
- hr = pdm->Open();
- if (SUCCEEDED(hr))
- {
- IEnumDiscMasterFormats *pef;
- hr = pdm->EnumDiscMasterFormats(&pef);
- if (SUCCEEDED(hr))
- {
- IID pFormats[2];
- hr = pef->Next(sizeof(pFormats)/sizeof(IID), pFormats, &nActual);
- if (SUCCEEDED(hr))
- {
- while(nActual--) { if (IID_IRedbookDiscMaster == pFormats[nActual]) break; }
- if (nActual != ((ULONG)-1))
- {
- IRedbookDiscMaster *pdf;
- hr = pdm->SetActiveDiscMasterFormat(IID_IRedbookDiscMaster, (void**)&pdf);
- if (SUCCEEDED(hr))
- {
- pdf->Release();
- hr = pdm->EnumDiscRecorders(&per);
- if (SUCCEEDED(hr))
- {
- while (S_OK== per->Next(1, &pdr, &nActual) && nActual > 0)
- {
- BSTR bstrPath;
- hr = pdr->GetPath(&bstrPath);
- if (SUCCEEDED(hr))
- {
- if (0 == lstrcmp(szTargetName, bstrPath))
- {
- pIMAPI->bRecorder = TRUE;
- if ((DMF_BASEPNPID & pIMAPI->header.fFlags) && FAILED(pdr->GetBasePnPID(&pIMAPI->bstrBasePnPID))) pIMAPI->bstrBasePnPID = NULL;
- if ((DMF_DISPLAYNAMES & pIMAPI->header.fFlags) && FAILED(pdr->GetDisplayNames(&pIMAPI->bstrVendorID, &pIMAPI->bstrProductID, &pIMAPI->bstrRevision)))
- {
- pIMAPI->bstrVendorID = NULL;
- pIMAPI->bstrProductID = NULL;
- pIMAPI->bstrRevision = NULL;
- }
- if (DMF_PATH & pIMAPI->header.fFlags)
- {
- pIMAPI->bstrPath = bstrPath;
- bstrPath = NULL;
- }
- if ((DMF_DRIVESTATE & pIMAPI->header.fFlags) && FAILED(pdr->GetRecorderState(&pIMAPI->ulDriveState))) pIMAPI->ulDriveState = (ULONG)-1;
- if ((DMF_DRIVETYPE & pIMAPI->header.fFlags) && FAILED(pdr->GetRecorderType(&pIMAPI->fDriveType))) pIMAPI->fDriveType = 0;
- if ((DMF_QUERYMEDIATYPE | DMF_QUERYMEDIAINFO) & pIMAPI->header.fFlags)
- {
- BOOL bTypeOk(FALSE), bInfoOk(FALSE);
- if (SUCCEEDED(pdr->OpenExclusive()))
- {
- if (0 == (DMF_QUERYMEDIATYPE & pIMAPI->header.fFlags) ||
- SUCCEEDED(pdr->QueryMediaType(&pIMAPI->fMediaType, &pIMAPI->fMediaFlags))) bTypeOk = TRUE;
- if (0 == (DMF_QUERYMEDIAINFO & pIMAPI->header.fFlags) ||
- SUCCEEDED(pdr->QueryMediaInfo(&pIMAPI->bSessions, &pIMAPI->bLastTrack, &pIMAPI->ulStartAddress,
- &pIMAPI->ulNextWritable, &pIMAPI->ulFreeBlocks))) bInfoOk = TRUE;
- pdr->Close();
- }
-
-
- if (!bTypeOk)
- {
- pIMAPI->fMediaType = -1;
- pIMAPI->fMediaFlags = -1;
- }
- if (!bInfoOk)
- {
- pIMAPI->bLastTrack = 0;
- pIMAPI->bSessions = 0;
- pIMAPI->ulFreeBlocks = 0;
- pIMAPI->ulNextWritable = 0;
- pIMAPI->ulStartAddress = 0;
- }
-
-
- }
- break;
- }
- if (bstrPath) SysFreeString(bstrPath);
- }
- pdr->Release();
- }
- per->Release();
- }
- }
- }
- }
- pef->Release();
- }
- pdm->Close();
- }
- pdm->Release();
- }
- }
- pIMAPI->header.result = hr;
- AsycOp_Complete(&pIMAPI->header);
- }
|