GetLogicalDriveStrings, where's the trick this time ?

Started by Phildefaix, July 24, 2006, 12:52:18 AM

Previous topic - Next topic

Phildefaix

 :eek Sorry to bother the masters around here, I've got a genuine newbe question : I'm damned trying to use the GetLogicalDriveStrings function in Win32 API to list all drive letters on a machine. I provided the function with the required arguments, then send the result as text of a MessageBox. But it displays only drive A:\ - Can't understand ! Here is the source code, I assembled it with MASM V9. Would somebody be nice to advise me ? Is it that the value of nBufferLength (I've set it to 0FFh) is not correct ? Or, does that lpBuffer need to be handled in a special way instead of being sent directly to the MessageBox function as lpText ? Don't know ! - Here's my bit of so called code :

.386
.model flat, stdcall

option casemap:none

    include \masm32\include\windows.inc
    include \masm32\include\kernel32.inc
    includelib \masm32\lib\kernel32.lib
    include \masm32\include\user32.inc
    includelib \masm32\lib\user32.lib

.data

Caption db "Retrieve logical drives string",0

MBStyle equ 0h
BufferLength equ 0FFh

.data?

TheString LPSTR ?

.code

Start:

        invoke GetLogicalDriveStrings, BufferLength, addr TheString
        invoke MessageBox, NULL, addr TheString,addr Caption, MBStyle
        invoke ExitProcess, NULL

End Start
;------------------------------------------------------------------------------------------------
; Thanks.
;Phil.



Darrel

GetLogicalDriveStrings May return more then one string each one is null terminated, the last one being double null terminated. MessageBox will only display the string up to the first null terminator.

Regards,

Darrel

dsouza123

TheString LPSTR ?

isn't reserving a buffer of 255 bytes just an uninitialized dword

it should be

TheString db 512 dup (?)  ; would handle 255+1 bytes or 255+1 words for unicode
or
TheString dw 256 dup (?)

if BufferLength equ 0FFh is correct.

PBrennick

And pay close attention to what Darrel said.  If you want to show the string of drives as one string in a message box then you need to parse the string looking for the double null.  Wherever you find a single null (look ahead to see the next char) replace it with a comma and loop back to get the next Character.  Once you find the double null, display the string in the message box.

HTH,
Paul
The GeneSys Project is available from:
The Repository or My crappy website

hutch--

Phildefaix,

Welcome on board, don't worry about asking questions, that is what the forum is for and there are a lot of people who will help you if they can and we make sure that no-one is hassled if they are learning.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

MichaelW

One method of handling the embedded nulls would be to replace them with spaces, using something like this (the code also verifies that the function succeeded):

    invoke GetLogicalDriveStrings, BufferLength, ADDR TheString
    .IF eax && eax < BufferLength
        mov edx, OFFSET TheString
      @@:
        cmp BYTE PTR[edx+4], 0      ; check for second null
        je  @F
        mov BYTE PTR[edx+3], " "    ; replace first with space
        add edx, 4
        jmp @B
      @@:
    .ENDIF

eschew obfuscation

Tedd

or replace the zeroes with carriage-returns (byte 0Dh) -- looks a little nicer :bg
(variations as CR, LF, and CR+LF seem to work fine, though I would stick with just CR)
No snowflake in an avalanche feels responsible.

P1

Phildefaix,

Welcome Aboard !!!   :U

The forum 'Search' and Google are your programming friends.   :dance:

I scan for my drive resources using WNetOpenEnum, WNetEnumResource & WNetCloseEnum.  I work on a network ( Though it works for non-networked machines as well. ) and having the additional information is usually needed.  You have the option of picking your resource type as well.

Regards,  P1  :8)

Ian_B

This might be a serendipitous thread for me to ask this question in...

I have written an app that uses SHBrowseForFolder/SHGetPathFromIDList to retrieve a user-supplied directory to do file operations in. I have presumed that the reply will always be a "normal"-looking drive/path specification, eg. C:\path\filename - I am not attached to a network, so I am unaware how a network drive would be reported, and I'd hoped/guessed that it would effectively be drive-mapped to a standard drive letter. Since a user has reported problems accessing their network drive, it appears I am mistaken.

So can anyone with experience of using network drives please advise how the drive spec will appear formatted in the output from SHBrowseForFolder/SHGetPathFromIDList, please...  ::)

EDIT:

Quote from: MSDNIf the location specified by the pidl parameter is not part of the file system, this function will fail.

Does this mean that a network drive is NOT part of the file system? Not having a network drive means I can't test the function output myself to see what's returned...

EDIT2:

Or should I be looking to see if this is a UNC path returned, ie. "\\servername\sharename\" instead of "C:\" ?

Ian_B

Tedd

Mapped network drives are considered part of the file-system and therefore appear with their mapped driver-letter (just as if they were local drives).
The path returned for a Network 'place' is of the form "\\hostname\folder"

(This was tested with ulFlags = BIF_RETURNONLYFSDIRS, and calling SHBrowseForFolder, followed by SHGetPathFromIDList.)
No snowflake in an avalanche feels responsible.

Ian_B

Thanks, Tedd! The stuff that Iczelion doesn't mention...  :bg

Phildefaix

 :bg Hia ! You're all nice people I tell you, no way to feel lost in here ! Learnt a lot from this thread within very short time. I finally parsed the content of the buffer pointed to by lpBuffer with MichaelW's code. It works very fine  :U Hum ... I'll now focus on understanding his code since my therapy in the matter of handling strings in ASM is just begining :green Thanks and greets to all :dance: