1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
|
static BOOL WinNT40ListPorts(LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue)
/* Unlike Win9x, information on serial ports registry storing in NT 4.0 is
* scarce. HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM is reliably
* documented to hold the names of all installed serial ports, but I haven't
* confirmed this for infrared ports and other nonstandard drivers.
* Descriptions stored under SERIALCOMM lack the "FRIENDLYNAME" found
* in Win9x, there's only the bare names of the ports.
*/
{
DWORD dwError=0;
HKEY hKey=NULL;
DWORD dwIndex;
LPTSTR lpValueName=NULL;
LPTSTR lpPortName=NULL;
if(dwError=RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"),
0,KEY_READ,&hKey)){
/* it is really strange that this key does not exist, but could happen in theory */
if(dwError==ERROR_FILE_NOT_FOUND)dwError=0;
goto end;
}
for(dwIndex=0;;++dwIndex){
DWORD cbValueName=32*sizeof(TCHAR);
DWORD cbPortName=32*sizeof(TCHAR);
LISTPORTS_PORTINFO portinfo;
/* loop asking for the value data til we allocated enough memory */
for(;;){
free(lpValueName);
if(!(lpValueName=(LPTSTR)malloc(cbValueName))){
dwError=ERROR_NOT_ENOUGH_MEMORY;
goto end;
}
free(lpPortName);
if(!(lpPortName=(LPTSTR)malloc(cbPortName))){
dwError=ERROR_NOT_ENOUGH_MEMORY;
goto end;
}
if(!(dwError=RegEnumValue(hKey,dwIndex,lpValueName,&cbValueName,
NULL,NULL,(LPBYTE)lpPortName,&cbPortName))){
break; /* we did it */
}
else if(dwError==ERROR_MORE_DATA){ /* not enough space */
dwError=0;
/* no indication of space required, we try doubling */
cbValueName=(cbValueName+sizeof(TCHAR))*2;
}
else goto end;
}
portinfo.lpPortName=lpPortName;
portinfo.lpFriendlyName=lpPortName; /* no friendly name in NT 4.0 */
portinfo.lpTechnology=TEXT(""); /* this information is not available */
if(!lpCbk(lpCbkValue,&portinfo)){
goto end; /* listing aborted by callback */
}
}
end:
free(lpValueName);
free(lpPortName);
if(hKey!=NULL)RegCloseKey(hKey);
if(dwError!=0){
SetLastError(dwError);
return FALSE;
}
else return TRUE;
}
|