As https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getlogicaldrivestringsw said, the sting in returned lpBuffer is
C:\\\0D:\\\0
then we can spilt at \0 to tell the real name of logical driver
Then I translate the code into nim
import winim
proc GetLogicalDriveStringsW(nBufferLength: DWORD; lpBuffer: LPTSTR): DWORD {.stdcall, dynlib: "kernel32", importc, discardable.}
var szAllDriveStrings = GetLogicalDriveStringsW(0, NULL)
echo szAllDriveStrings
if szAllDriveStrings > 0:
var lpDriveStrings:LPTSTR = cast[LPTSTR](HeapAlloc(GetProcessHeap(), 0, cast[SIZE_T](szAllDriveStrings*sizeof(TCHAR))))
GetLogicalDriveStringsW(szAllDriveStrings, lpDriveStrings)
echo lpDriveStrings # only C:\
var x = newString(szAllDriveStrings*sizeof(TCHAR))
copyMem(addr(x[0]), lpDriveStrings, szAllDriveStrings*sizeof(TCHAR))
echo x # C:\D:\
so what is the proper way to deal with C's LPTSTR, how can I get C:`, `D:`? No I don't think I sould split the string at `` then attach `` to `C: and D:?
to be more common, what if there are more \0 in a C string, how can we deal the information correctly in nim?
thanks
Here you go:
https://play.nim-lang.org/#ix=2d96
As I don't use Windows, I can't verify the code and have only written it based on documentations lying around.
Please note that the string that GetLogicalDriveStringsW returns is a wide string, not a C string, and along with it's other API quirks, I'd say that correctly getting a buffer was not as easy as I imagined.
to be more common, what if there are many 0 in a C string, how can we deal the information correctly in nim?
Hope this helps: https://play.nim-lang.org/#ix=2d9d
psutil has this function in case you'd rather use that (or see how we did it).
import psutil
echo disk_partitions()
produces:
@[(device: "C:\\", mountpoint: "C:\\", fstype: "NTFS", opts: "rw,fixed"), (device: "D:\\", mountpoint: "D:\\", fstype: "NTFS", opts: "rw,fixed")]
You can try running this code with different mode:
import winim/lean, strutils
var bufLen = GetLogicalDriveStrings(0, nil)
var buffer = T(bufLen)
GetLogicalDriveStrings(bufLen, buffer)
echo buffer
echo buffer.repr
echo ($buffer).repr
echo cstring($buffer)
echo ($buffer).split('\0')
nim c -r test.nim
nim c -r -d:useWinAnsi test.nim