1. Ugh, stupid TCHAR problems. Anyone able to tell me how to fix this in EUcode?

The function should return a text buffer I can parse to get the local system's drives. Unfortunately the API function returns the text in a TCHAR buffer which creates garbage output when I try to read it. Here is my code:

constant kernel32 = open_dll( "kernel32.dll" ), 
                 xGetFreeSpace = define_c_func(kernel32, "GetDiskFreeSpaceExA",  
{C_POINTER, C_POINTER, C_POINTER, C_POINTER}, C_INT), 
                 xGetMetrics = define_c_func(kernel32, "GetDiskFreeSpaceA",  
{C_POINTER, C_POINTER, C_POINTER, C_POINTER, C_POINTER}, C_INT), 
                 xGetDriveType = define_c_func(kernel32, "GetDriveTypeA",  
{C_POINTER}, C_INT), 
                 xGetDriveStrings = define_c_func(kernel32, "GetLogicalDriveStringsA",  
{C_DOUBLE, C_POINTER}, C_INT) 
 
global function get_all_drives() 
 
	sequence drivestrings 
	atom retptr, converted_addr 
	 
	atom buflen 
 
	retptr = allocate(8)	-- allocate 8 bytes for the pointer to the buffer 
	 
	buflen = c_func(xGetDriveStrings, {200, retptr})  
        -- bufeln s/b size of buffer, 200 = max size I am allowing buffer, retptr should catch 
        -- address of buffer 
 
	if buflen > 0 then       -- function has given me a vale > 0 so function succeeded 
		-- ok to work 
		drivestrings = sprintf("GOOD RETURN: %d  ", {buflen}) 
-- convert 8 bytes to address 
                converted_addr = peek4u(retptr)+(peek4u(retptr+4) * #100000000)   
-- peek the text from the buffer  
		drivestrings &= w32peek_string(converted_addr) 	 
 
	else 
		drivestrings = "BAD RETURN" 
	end if 
	 
	free(retptr) 
	 
	return drivestrings 
	 
end function 
 

On my system this code creates the output: GOOD RETURN: 37 222222

EDIT: The output should show the character representations of all my computer drives. (i.e. C:, D:, etc.) EDIT2: I have 9 drives on my system so 3 chars + null * 9 + end null = 37. The function seems to be returning correctly... just don't know how to read the buffer. :(

The MSDN reference site for GetLogicalDriveStringsA says that it creates a buffer using TCHARs. So how can I convert these to a regular euphoria character string?

Any help, as always, is greatly appreciated! I'm using EU 3.1.1

Thanks! Steve A.

new topic     » topic index » view message » categorize

2. Re: Ugh, stupid TCHAR problems. Anyone able to tell me how to fix this in EUcode?

ssallen said...

The function should return a text buffer I can parse to get the local system's drives. Unfortunately the API function returns the text in a TCHAR buffer which creates garbage output when I try to read it. Here is my code:

constant kernel32 = open_dll( "kernel32.dll" ), 
                 xGetFreeSpace = define_c_func(kernel32, "GetDiskFreeSpaceExA",  
{C_POINTER, C_POINTER, C_POINTER, C_POINTER}, C_INT), 
                 xGetMetrics = define_c_func(kernel32, "GetDiskFreeSpaceA",  
{C_POINTER, C_POINTER, C_POINTER, C_POINTER, C_POINTER}, C_INT), 
                 xGetDriveType = define_c_func(kernel32, "GetDriveTypeA",  
{C_POINTER}, C_INT), 
                 xGetDriveStrings = define_c_func(kernel32, "GetLogicalDriveStringsA",  
{C_DOUBLE, C_POINTER}, C_INT) 
 
global function get_all_drives() 
 
	sequence drivestrings 
	atom retptr 
	 
	atom buflen 
 
	retptr = allocate(8)	 
	 
	buflen = c_func(xGetDriveStrings, {200, retptr})  
 
	if buflen > 0 then 
		-- ok to work 
		drivestrings = sprintf("GOOD RETURN: %d  ", {buflen}) 
		drivestrings &= w32peek_string(peek4u(retptr)+(peek4u(retptr+4) * #100000000)) 	 
 
	else 
		drivestrings = "BAD RETURN" 
	end if 
	 
	free(retptr) 
	 
	return drivestrings 
	 
end function 
 

On my system this code creates the output: GOOD RETURN: 37 222222

EDIT: The output should show the character representations of all my computer drives. (i.e. C:, D:, etc.)

The MSDN reference site for GetLogicalDriveStringsA says that it creates a buffer using TCHARs. So how can I convert these to a regular euphoria character string?

Any help, as always, is greatly appreciated! I'm using EU 3.1.1

Thanks! Steve A.

http://msdn.microsoft.com/en-us/library/cc842072.aspx

So a TCHAR, for the ANSI version, is just a regular char. So using peek_string() should work fine.

The real issue is not TCHAR related, but I suspect, it is because you are using the function incorrectly. An 8 byte buffer is not large enough to hold 200 chars, and the buffer is filled with multiple null terminated strings right next to each other, which makes your code (which appears to attempt to derive a pointer from the contents of a buffer) hard to understand.

new topic     » goto parent     » topic index » view message » categorize

3. Re: Ugh, stupid TCHAR problems. Anyone able to tell me how to fix this in EUcode?

Hi Jim,

The MSDN documentation describes the parameters for the function as follows: DWORD WINAPI GetLogicalDriveStrings( in DWORD nBufferLength, out LPTSTR lpBuffer );

"nBufferLength [in] The maximum size of the buffer pointed to by lpBuffer, in TCHARs. This size does not include the terminating null character. If this parameter is zero, lpBuffer is not used.

lpBuffer [out] A pointer to a buffer that receives a series of null-terminated strings, one for each valid drive in the system, plus with an additional null character. Each string is a device name."

So when I am calling the function I am using retptr as the pointer that holds the address of the txt buffer. The 8 bytes is just to hold the address of the buffer... not the buffer itself. At least thats how I understand it. The 200 that is passed was just an arbitrary value that I felt was big enough of a buffer to hold my system information... since I am not entirely sure what the output from the c function will actually look like. The function itself is WINAPI. Buflen is the functin return that tells me how long the buffer actually is. Does that clear it up? I'm going to clear up the code and comment it a bit more maybe then it will be easier to explain what I am doing wrong.

EDIT: commented original code better.

new topic     » goto parent     » topic index » view message » categorize

4. Re: Ugh, stupid TCHAR problems. Anyone able to tell me how to fix this in EUcode?

ssallen said...

Hi Jim,

So when I am calling the function I am using retptr as the pointer that holds the address of the txt buffer. The 8 bytes is just to hold the address of the buffer... not the buffer itself. At least thats how I understand it.

This is wrong. I feel the confusion comes from C code, in which any array or string is automatically a pointer as well.

You need to allocate a space of size 200, to match the buffer length you are passing in. Or, you could call the function with 0 and NULL, in which case only the length of the buffer is returned. Then you can allocate a buffer of the right size and call the function again.

ssallen said...

The 200 that is passed was just an arbitrary value that I felt was big enough of a buffer to hold my system information... since I am not entirely sure what the output from the c function will actually look like. The function itself is WINAPI. Buflen is the functin return that tells me how long the buffer actually is. Does that clear it up? I'm going to clear up the code and comment it a bit more maybe then it will be easier to explain what I am doing wrong.

From this, I believe I have understood your code correctly and I maintain that you are calling it incorrectly, based on this example: http://www.codeguru.com/forum/archive/index.php/t-252784.html

That example can be converted to Euphoria code like this:

atom pch 
atom szBuffer 
szBuffer = allocate(1024) 
? c_func(GetDriveLogicalSpace_, {1024, szBuffer}) 
pch = szBuffer 
while peek(pch) != 0 do 
	puts(1, peek_string(pch) & '\n') 
	pch = pch + length(peek_string(pch)) + 1 
end while 
new topic     » goto parent     » topic index » view message » categorize

5. Re: Ugh, stupid TCHAR problems. Anyone able to tell me how to fix this in EUcode?

Your code is incorrect.

The second parameter to GetLogicalDriveStrings() is a pointer to a buffer that holds the returned strings. It is not a pointer to a pointer. The first parameter is the length of this buffer.

The result is a series of null terminated strings. This will in the form: C:\(NULL)D:\(NULL)

(NULL) is a single zero character.

I have used this function as described and know it works.

new topic     » goto parent     » topic index » view message » categorize

6. Re: Ugh, stupid TCHAR problems. Anyone able to tell me how to fix this in EUcode?

Ok, so I replaced my code with what Jim provided and my output still looks like rubbish:

37 2 rubbish characters.

My new code looks like this:

constant kernel32 = open_dll( "kernel32.dll" ), 
                 xGetFreeSpace = define_c_func(kernel32, "GetDiskFreeSpaceExA",  
{C_POINTER, C_POINTER, C_POINTER, C_POINTER}, C_INT), 
                 xGetMetrics = define_c_func(kernel32, "GetDiskFreeSpaceA",  
{C_POINTER, C_POINTER, C_POINTER, C_POINTER, C_POINTER}, C_INT), 
                 xGetDriveType = define_c_func(kernel32, "GetDriveTypeA",  
{C_POINTER}, C_INT), 
                 xGetDriveStrings = define_c_func(kernel32, "GetLogicalDriveStringsA",  
{C_DOUBLE, C_POINTER}, C_INT) 
 
global function get_all_drives() 
 
atom pch  
atom szBuffer  
szBuffer = allocate(1024)  
? c_func(xGetDriveStrings, {1024, szBuffer})  
pch = szBuffer  
while peek(pch) != 0 do  
	puts(1, peek_string(pch) & '\n')  
	pch = pch + length(peek_string(pch)) + 1  
end while  
 
return "" 
	 
end function 
 
 

Obviously I just added the code into my old function to see the console output. Is my declaration calling the dll incorrect then?

Thanks! Steve A.

new topic     » goto parent     » topic index » view message » categorize

7. Re: Ugh, stupid TCHAR problems. Anyone able to tell me how to fix this in EUcode?

ssallen said...

Obviously I just added the code into my old function to see the console output. Is my declaration calling the dll incorrect then?

Thanks! Steve A.

Yes. The first parameter should be C_INT, not C_DOUBLE.

new topic     » goto parent     » topic index » view message » categorize

8. Re: Ugh, stupid TCHAR problems. Anyone able to tell me how to fix this in EUcode?

That did the trick! Thanks gentlemen!

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu