The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: Phildefaix on July 24, 2006, 12:52:18 AM

Title: GetLogicalDriveStrings, where's the trick this time ?
Post by: Phildefaix on July 24, 2006, 12:52:18 AM
 :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.


Title: Re: GetLogicalDriveStrings, where's the trick this time ?
Post by: Darrel on July 24, 2006, 01:37:00 AM
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
Title: Re: GetLogicalDriveStrings, where's the trick this time ?
Post by: dsouza123 on July 24, 2006, 02:00:28 AM
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.
Title: Re: GetLogicalDriveStrings, where's the trick this time ?
Post by: PBrennick on July 24, 2006, 06:32:29 AM
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
Title: Re: GetLogicalDriveStrings, where's the trick this time ?
Post by: hutch-- on July 24, 2006, 06:48:22 AM
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.
Title: Re: GetLogicalDriveStrings, where's the trick this time ?
Post by: MichaelW on July 24, 2006, 08:43:25 AM
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

Title: Re: GetLogicalDriveStrings, where's the trick this time ?
Post by: Tedd on July 24, 2006, 10:16:41 AM
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)
Title: Re: GetLogicalDriveStrings, where's the trick this time ?
Post by: P1 on July 24, 2006, 02:07:58 PM
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)
Title: Re: GetLogicalDriveStrings, where's the trick this time ?
Post by: Ian_B on July 24, 2006, 04:04:07 PM
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
Title: Re: GetLogicalDriveStrings, where's the trick this time ?
Post by: Tedd on July 24, 2006, 04:35:05 PM
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.)
Title: Re: GetLogicalDriveStrings, where's the trick this time ?
Post by: Ian_B on July 24, 2006, 04:41:56 PM
Thanks, Tedd! The stuff that Iczelion doesn't mention...  :bg
Title: Re: GetLogicalDriveStrings, where's the trick this time ?
Post by: Phildefaix on July 24, 2006, 11:15:06 PM
 :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: