{"record":{"id":"2fb99c1c2ff82a68","repo":"java-native-access/jna","slug":"win32exception-from-native-getlasterror-after-querydosdevice","errorCode":null,"errorMessage":"Win32Exception from native GetLastError after QueryDosDevice returned 0","messagePattern":"Win32Exception from native GetLastError after QueryDosDevice returned 0","errorType":"error_code","errorClass":"Win32Exception","httpStatus":null,"severity":"error","filePath":"contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java","lineNumber":851,"sourceCode":"            buffer.append(string).append('\\0');\n        buffer.append('\\0');\n        if (! Kernel32.INSTANCE.WritePrivateProfileSection(appName, buffer.toString(), fileName)) {\n            throw new Win32Exception(Kernel32.INSTANCE.GetLastError());\n        }\n    }\n\n    /**\n     * Invokes the {@link Kernel32#QueryDosDevice(String, char[], int)} method\n     * and parses the result\n     * @param lpszDeviceName The device name\n     * @param maxTargetSize The work buffer size to use for the query\n     * @return The parsed result\n     */\n    public static final List<String> queryDosDevice(String lpszDeviceName, int maxTargetSize) {\n        char[] lpTargetPath = new char[maxTargetSize];\n        int dwSize = Kernel32.INSTANCE.QueryDosDevice(lpszDeviceName, lpTargetPath, lpTargetPath.length);\n        if (dwSize == 0) {\n            throw new Win32Exception(Kernel32.INSTANCE.GetLastError());\n        }\n\n        return Native.toStringList(lpTargetPath, 0, dwSize);\n    }\n\n    /**\n     * Invokes and parses the result of {@link Kernel32#GetVolumePathNamesForVolumeName(String, char[], int, IntByReference)}\n     * @param lpszVolumeName The volume name\n     * @return The parsed result\n     * @throws Win32Exception If failed to retrieve the required information\n     */\n    public static final List<String> getVolumePathNamesForVolumeName(String lpszVolumeName) {\n        char[] lpszVolumePathNames = new char[WinDef.MAX_PATH + 1];\n        IntByReference lpcchReturnLength = new IntByReference();\n\n        if (!Kernel32.INSTANCE.GetVolumePathNamesForVolumeName(lpszVolumeName, lpszVolumePathNames, lpszVolumePathNames.length, lpcchReturnLength)) {\n            int hr = Kernel32.INSTANCE.GetLastError();\n            if (hr != WinError.ERROR_MORE_DATA) {","sourceCodeStart":833,"sourceCodeEnd":869,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java#L833-L869","documentation":"queryDosDevice resolves a DOS device name (e.g. \"C:\") to its native target via the Win32 QueryDosDevice API. A return size of 0 signals failure, and the wrapper throws Win32Exception carrying GetLastError — most often ERROR_FILE_NOT_FOUND because the device name does not exist. The result is parsed into a list of null-terminated strings.","triggerScenarios":"Calling Kernel32Util.queryDosDevice(lpszDeviceName, maxTargetSize) when QueryDosDevice returns 0 — the DOS device name does not exist (typo or drive letter not mounted), the buffer (maxTargetSize) is too small for the target path, or the name contains invalid characters.","commonSituations":"Checking a mapped drive that was disconnected/unmounted; querying subst or symbolically linked device names that were removed; passing a name with a trailing backslash when the API expects none; using too small maxTargetSize for very long UNC targets.","solutions":["Validate the device name exists first (e.g. new File(\"C:\\\\\").exists() or QueryDosDevice with null to list all names).","Pass the device name WITHOUT a trailing backslash (\"C:\" not \"C:\\\\\").","Increase maxTargetSize (e.g. 1024) if ERROR_INSUFFICIENT_BUFFER is the reported code.","Catch Win32Exception and treat ERROR_FILE_NOT_FOUND as 'device absent' rather than a hard failure."],"exampleFix":"// before\nList<String> targets = Kernel32Util.queryDosDevice(\"Z:\", 260); // may throw if Z: unmounted\n\n// after\ntry {\n    List<String> targets = Kernel32Util.queryDosDevice(\"Z:\", 1024);\n} catch (Win32Exception e) {\n    if (e.getErrorCode() == WinError.ERROR_FILE_NOT_FOUND) {\n        targets = Collections.emptyList(); // drive not mapped\n    } else {\n        throw e;\n    }\n}","handlingStrategy":"try-catch","validationCode":"if (lpszDeviceName.endsWith(\"\\\\\")) {\n    throw new IllegalArgumentException(\"Device name must not end with backslash: \" + lpszDeviceName);\n}","typeGuard":null,"tryCatchPattern":"try {\n    return Kernel32Util.queryDosDevice(name, 1024);\n} catch (Win32Exception e) {\n    if (e.getErrorCode() == WinError.ERROR_FILE_NOT_FOUND) {\n        return Collections.emptyList();\n    }\n    throw e;\n}","preventionTips":["Strip trailing backslashes from device names.","Use a generous buffer size (>=1024).","Treat ERROR_FILE_NOT_FOUND as 'device not mounted', not a crash.","Validate mapped drives still exist before use."],"tags":["win32","device","jna"],"backgroundTag":"win32-native-error","analyzedSha":"d036ad9781adad4b66693e8fa7098e4ac665e0a3","analyzedAt":"2026-09-12T06:50:59.239Z","contentChangedAt":"2026-09-12T06:50:59.239Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}