Changelog ------------ moved implementation of QueryDosDevice from ascii to unicode
--- ../wine/files/dos_fs.c Wed Aug 20 18:16:29 2003 +++ files/dos_fs.c Fri Aug 22 16:20:27 2003 @@ -111,6 +111,18 @@ { {'E','M','M','X','X','X','X','0',0}, 0x0000 } }; +static const WCHAR devW[] = {'\\','D','e','v','i','c','e','\\',0}; +static const WCHAR dosW[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\',0}; + +static const WCHAR auxW[] = {'A','U','X',0}; +static const WCHAR comW[] = {'C','O','M',0}; +static const WCHAR lptW[] = {'L','P','T',0}; +static const WCHAR nulW[] = {'N','U','L',0}; + +static const WCHAR nullW[] = {'N','u','l','l',0}; +static const WCHAR parW[] = {'P','a','r','a','l','l','e','l',0}; +static const WCHAR serW[] = {'S','e','r','i','a','l',0}; + /* * Directory info for DOSFS_ReadDir * contains the names of *all* the files in the directory @@ -2354,15 +2366,67 @@ */ DWORD WINAPI QueryDosDeviceA(LPCSTR devname,LPSTR target,DWORD bufsize) { - LPSTR s; - char buffer[200]; + DWORD ret = 0, retW; + LPWSTR targetW = (LPWSTR)HeapAlloc(GetProcessHeap(),0, + bufsize * sizeof(WCHAR)); + UNICODE_STRING devnameW; + + if(devname) RtlCreateUnicodeStringFromAsciiz(&devnameW, devname); + else devnameW.Buffer = NULL; + + retW = QueryDosDeviceW(devnameW.Buffer, targetW, bufsize); - TRACE("(%s,...)\n", devname ? devname : "<null>"); + ret = WideCharToMultiByte(CP_ACP, 0, targetW, retW, target, + bufsize, NULL, NULL); + + RtlFreeUnicodeString(&devnameW); + if (targetW) HeapFree(GetProcessHeap(),0,targetW); + return ret; +} + + +/*********************************************************************** + * QueryDosDeviceW (KERNEL32.@) + * + * returns array of strings terminated by \0, terminated by \0 + * + * FIXME + * - Win9x returns for all calls ERROR_INVALID_PARAMETER + * - the returned devices for devname == NULL is far from complete + * - its not checked that the returned device exists + */ +DWORD WINAPI QueryDosDeviceW(LPCWSTR devname,LPWSTR target,DWORD bufsize) +{ + WCHAR *pDev, *pName, *pNum = NULL; + int inst=-1, numsiz=0; + DWORD ret; + + TRACE("(%s,...)\n", debugstr_w(devname)); if (!devname) { /* return known MSDOS devices */ - static const char devices[24] = "CON\0COM1\0COM2\0LPT1\0NUL\0\0"; - memcpy( target, devices, min(bufsize,sizeof(devices)) ); - return min(bufsize,sizeof(devices)); + DWORD ret = 0; + int i; + static const WCHAR devices[][5] = {{'A','U','X',0}, + {'C','O','M','1',0}, + {'C','O','M','2',0}, + {'L','P','T','1',0}, + {'N','U','L',0,}}; + for(i=0; (i< (sizeof(devices)/sizeof(devices[0]))); i++) { + DWORD len = strlenW(devices[i]); + if(target && (bufsize >= ret + len + 2)) { + lstrcpyW(target+ret, devices[i]); + ret += len + 1; + } else { + /* in this case WinXP returns 0 */ + FIXME("function return is wrong for WinXP!\n"); + SetLastError(ERROR_INSUFFICIENT_BUFFER); + break; + } + } + /* append drives here */ + if(target && bufsize > 0) target[ret++] = 0; + FIXME("Returned list is not complete\n"); + return ret; } /* In theory all that are possible and have been defined. * Now just those below, since mirc uses it to check for special files. @@ -2370,39 +2434,50 @@ * (It is more complex, and supports netmounted stuff, and \\.\ stuff, * but currently we just ignore that.) */ -#define CHECK(x) (strstr(devname,#x)==devname) - if (CHECK(con) || CHECK(com) || CHECK(lpt) || CHECK(nul)) { - strcpy(buffer,"\\DEV\\"); - strcat(buffer,devname); - if ((s=strchr(buffer,':'))) *s='\0'; - lstrcpynA(target,buffer,bufsize); - return strlen(buffer)+1; - } else { - if (strchr(devname,':') || devname[0]=='\\') { - /* This might be a DOS device we do not handle yet ... */ - FIXME("(%s) not detected as DOS device!\n",devname); + if (!strcmpiW(devname, auxW)) { + pDev = (WCHAR*) dosW; + pName = (WCHAR*) comW; + numsiz = inst = 1; + pNum = (WCHAR*) L"1"; + } else if (!strcmpiW(devname, nulW)) { + pDev = (WCHAR*) devW; + pName = (WCHAR*) nullW; + } else if (!strncmpiW(devname, comW, strlenW(comW))) { + pDev = (WCHAR*) devW; + pName = (WCHAR*) serW; + pNum = (WCHAR* )devname + strlenW(comW); + swscanf(pNum, L"%d%n", &inst, &numsiz); + if(*(pNum + numsiz)) { + SetLastError(ERROR_FILE_NOT_FOUND); + return 0; } - SetLastError(ERROR_DEV_NOT_EXIST); + } else if (!strncmpiW(devname, lptW, strlenW(lptW))) { + pDev = (WCHAR*) devW; + pName = (WCHAR*) parW; + pNum = (WCHAR*) devname + strlenW(lptW); + swscanf(pNum, L"%d%n", &inst, &numsiz); + if(*(pNum + numsiz)) { + SetLastError(ERROR_FILE_NOT_FOUND); return 0; } + } else { + /* This might be a DOS device we do not handle yet ... */ + FIXME("(%s) not detected as DOS device!\n",debugstr_w(devname)); + /* Win9x set the error ERROR_INVALID_PARAMETER */ + SetLastError(ERROR_FILE_NOT_FOUND); + return 0; } + FIXME("device %s may not exist on this computer\n", debugstr_w(devname)); - -/*********************************************************************** - * QueryDosDeviceW (KERNEL32.@) - * - * returns array of strings terminated by \0, terminated by \0 - */ -DWORD WINAPI QueryDosDeviceW(LPCWSTR devname,LPWSTR target,DWORD bufsize) -{ - LPSTR devnameA = devname?HEAP_strdupWtoA(GetProcessHeap(),0,devname):NULL; - LPSTR targetA = (LPSTR)HeapAlloc(GetProcessHeap(),0,bufsize); - DWORD ret = QueryDosDeviceA(devnameA,targetA,bufsize); - - ret = MultiByteToWideChar( CP_ACP, 0, targetA, ret, target, bufsize ); - if (devnameA) HeapFree(GetProcessHeap(),0,devnameA); - if (targetA) HeapFree(GetProcessHeap(),0,targetA); + ret = strlenW(pDev) + strlenW(pName) + numsiz + 2; + if (ret > bufsize) ret = 0; + if (target && ret) { + lstrcpyW(target,pDev); + lstrcatW(target,pName); + if (pNum) lstrcatW(target,pNum); + target[ret-1] = 0; + } return ret; }