I wrote the next source code, but when i run it doesnt work. Every time i received error 610. I read MSDN but i don't see why it doesnt work.
;-------------------------------------------------------------------------
GetDialUp PROC
MAX_ENTRIES EQU 100
LOCAL RASMemoryBuffer:DWORD
LOCAL dwEntryInfoSize:DWORD
INVOKE RasGetEntryProperties, 0, 0, 0, ADDR dwEntryInfoSize, 0, 0
m2m lpcb, dwEntryInfoSize
INVOKE GlobalAlloc,GMEM_FIXED OR GMEM_ZEROINIT,dwEntryInfoSize
.IF eax == -1
mov eax, 0
RET
.ENDIF
mov RASMemoryBuffer,eax
mov edi, RASMemoryBuffer
assume edi:PTR RASENTRYNAME
mov .dwSize, SIZEOF(RASENTRYNAME)
INVOKE RasEnumEntries, 0, 0, edi, ADDR lpcb, ADDR lpcEntries
INVOKE PrintEAX, eax
cmp eax, 0 ;eax = ERROR_BUFFER_INVALID (code 610)
je lab3190
szText Str2, "RasEnumEntries error?"
INVOKE MessageBox,NULL,ADDR Str2,ADDR AppName,MB_OK
jmp lab3208
lab3190:
...........
lab3208:
assume edi:nothing
INVOKE GlobalFree, RASMemoryBuffer
RET
GetDialUp ENDP
;-------------------------------------------------------------------------
Please help me
;-------------------------------------------------------------------------
GetDialUp PROC
MAX_ENTRIES EQU 100
LOCAL RASMemoryBuffer:DWORD
LOCAL dwEntryInfoSize:DWORD
INVOKE RasGetEntryProperties, 0, 0, 0, ADDR dwEntryInfoSize, 0, 0
m2m lpcb, dwEntryInfoSize
INVOKE GlobalAlloc,GMEM_FIXED OR GMEM_ZEROINIT,dwEntryInfoSize
.IF eax == -1
mov eax, 0
RET
.ENDIF
mov RASMemoryBuffer,eax
mov edi, RASMemoryBuffer
assume edi:PTR RASENTRYNAME
mov .dwSize, SIZEOF(RASENTRYNAME)
INVOKE RasEnumEntries, 0, 0, edi, ADDR lpcb, ADDR lpcEntries
INVOKE PrintEAX, eax
cmp eax, 0 ;eax = ERROR_BUFFER_INVALID (code 610)
je lab3190
szText Str2, "RasEnumEntries error?"
INVOKE MessageBox,NULL,ADDR Str2,ADDR AppName,MB_OK
jmp lab3208
lab3190:
...........
lab3208:
assume edi:nothing
INVOKE GlobalFree, RASMemoryBuffer
RET
GetDialUp ENDP
;-------------------------------------------------------------------------
Please help me
Wild guess (can't try it right now):
Change
INVOKE RasEnumEntries, 0, 0, edi, ADDR lpcb, ADDR lpcEntries
to
INVOKE RasEnumEntries, 0, 0, , ADDR lpcb, ADDR lpcEntries
And better dont use EDI, because it might get changed by the API call.
Change
INVOKE RasEnumEntries, 0, 0, edi, ADDR lpcb, ADDR lpcEntries
to
INVOKE RasEnumEntries, 0, 0, , ADDR lpcb, ADDR lpcEntries
And better dont use EDI, because it might get changed by the API call.
Interesting. All seems to be workable, but...
I traced inside RasEnumEntries and discovered that it expects 108h in first dword of buffer pointed by lprasentryname. It's size of RASENTRYNAME structure as it should be.
But currently RASENTRYNAME defined like this:
And its size is 105h.
It's correct, IMHO, because in M$'s res.h RASENTRYNAMEA is also defined like this:
I have currently no c compiler, but, anyway,
all this means that 3-bytes padding should be added at the end of RASENTRYNAMEA.
And actually it should be defined like this:
That was first problem.
The next one. RasEnumEntries wants buffer which size is larger than RasGetEntryProperties returns.
So first time you call RasEnumEntries, it returns ERROR_BUFFER_TOO_SMALL and sets cb to the number of bytes required. So, you have to realloc more memory and call it again.
Below is workable ex:
PS: Don't forget add padding to RASENTRYNAMEA definition, otherwise you can't correctly access its members.
Edited: I've tested it uder w98 only. As for w2k/xp, other members (dwFlags and szPhonebookPath) should be added, i guess, because its version >= 5.0.
I traced inside RasEnumEntries and discovered that it expects 108h in first dword of buffer pointed by lprasentryname. It's size of RASENTRYNAME structure as it should be.
But currently RASENTRYNAME defined like this:
RAS_MaxEntryName equ 256
RASENTRYNAMEA STRUCT
dwSize dd ?
szEntryName db RAS_MaxEntryName + 1 dup(?)
RASENTRYNAMEA ENDS
And its size is 105h.
It's correct, IMHO, because in M$'s res.h RASENTRYNAMEA is also defined like this:
#define RAS_MaxEntryName 256
#define RASENTRYNAMEA struct tagRASENTRYNAMEA
RASENTRYNAMEA
{
DWORD dwSize;
CHAR szEntryName[ RAS_MaxEntryName + 1 ];
#if (WINVER >= 0x500)
DWORD dwFlags;
CHAR szPhonebookPath[MAX_PATH + 1];
#endif
};
I have currently no c compiler, but, anyway,
all this means that 3-bytes padding should be added at the end of RASENTRYNAMEA.
And actually it should be defined like this:
RASENTRYNAMEA STRUCT
dwSize dd ?
szEntryName db RAS_MaxEntryName + 1 dup(?)
[color=red]db 3 dup(?)[/color] ; add this line
RASENTRYNAMEA ENDS
That was first problem.
The next one. RasEnumEntries wants buffer which size is larger than RasGetEntryProperties returns.
So first time you call RasEnumEntries, it returns ERROR_BUFFER_TOO_SMALL and sets cb to the number of bytes required. So, you have to realloc more memory and call it again.
Below is workable ex:
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\rasapi32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\rasapi32.lib
.data
Str2 db "RasEnumEntries error?", 0
cb UINT 0
cEntries UINT 0
szEmpty db 0
.code
GetDialUp proc uses edi
MAX_ENTRIES EQU 100
LOCAL RASMemoryBuffer:DWORD
LOCAL dwEntryInfoSize:DWORD
LOCAL hHeap:HANDLE
and dwEntryInfoSize, 0
INVOKE RasGetEntryProperties, 0, 0, 0, ADDR dwEntryInfoSize, 0, 0
push dwEntryInfoSize
pop cb
invoke GetProcessHeap
mov hHeap, eax
invoke HeapAlloc, hHeap, HEAP_ZERO_MEMORY, dwEntryInfoSize
mov edi, eax
mov RASMemoryBuffer,eax
mov edi, eax
assume edi:PTR RASENTRYNAME
mov [edi].dwSize, SIZEOF(RASENTRYNAME)
INVOKE RasEnumEntries, 0, 0, edi, ADDR cb, ADDR cEntries
.if eax == ERROR_BUFFER_TOO_SMALL
invoke HeapReAlloc, hHeap, HEAP_ZERO_MEMORY, edi, cb
invoke RasEnumEntries, 0, 0, edi, ADDR cb, ADDR cEntries
.endif
;INVOKE PrintEAX, eax
cmp eax, 0 ;eax = ERROR_BUFFER_INVALID (code 610)
je lab3190
INVOKE MessageBox, NULL, ADDR Str2, NULL, MB_OK
jmp lab3208
lab3190:
;...........
lab3208:
assume edi:nothing
invoke HeapFree, hHeap, 0, edi
;INVOKE GlobalFree, RASMemoryBuffer
RET
GetDialUp ENDP
start:
invoke GetDialUp
invoke ExitProcess, 0
ret
end start
PS: Don't forget add padding to RASENTRYNAMEA definition, otherwise you can't correctly access its members.
Edited: I've tested it uder w98 only. As for w2k/xp, other members (dwFlags and szPhonebookPath) should be added, i guess, because its version >= 5.0.
I've just compiled some ex on msvc6 and satisfied myself that 3-padding is really added.
So...
w9x RASENTRYNAMEA
w2k, + RASENTRYNAMEA
==================================================
Example for w2k:
So...
w9x RASENTRYNAMEA
RASENTRYNAMEA STRUCT
dwSize dd ?
szEntryName db RAS_MaxEntryName + 1 dup(?)
db 3 dup(?)
RASENTRYNAMEA ENDS
w2k, + RASENTRYNAMEA
RASENTRYNAMEA STRUCT
dwSize dd ?
szEntryName db RAS_MaxEntryName + 1 dup(?)
db 3 dup(?)
dwFlags dd ?
szPhonebookPath db MAX_PATH + 1 dup(?)
db 3 dup(?)
RASENTRYNAMEA ENDS
==================================================
Example for w2k:
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\rasapi32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\rasapi32.lib
MAX_ENTRYES equ 20
RASENTRYNAMEA_ STRUCT
dwSize dd ?
szEntryName db RAS_MaxEntryName + 1 dup(?)
db 3 dup(?)
dwFlags dd ?
szPhonebookPath db MAX_PATH + 1 dup(?)
db 3 dup(?)
RASENTRYNAMEA_ ENDS
.data
szCaption db "Remote access phone book", 0
NewLine db 10, 13, 0
.data?
buffer CHAR MAX_ENTRYES*256 dup(?)
.code
PhoneBook proc uses esi edi
LOCAL dwEntryInfoSize:DWORD
LOCAL hHeap:HANDLE
LOCAL cEntries:UINT
and dwEntryInfoSize, 0
invoke RasGetEntryProperties, 0, 0, 0, addr dwEntryInfoSize, 0, 0
invoke GetProcessHeap
mov hHeap, eax
invoke HeapAlloc, hHeap, HEAP_ZERO_MEMORY, dwEntryInfoSize
mov edi, eax
assume edi:PTR RASENTRYNAMEA_
mov [edi].dwSize, sizeof RASENTRYNAMEA_
invoke RasEnumEntries, 0, 0, edi, addr dwEntryInfoSize, addr cEntries
.if eax == ERROR_BUFFER_TOO_SMALL
invoke HeapReAlloc, hHeap, HEAP_ZERO_MEMORY, edi, dwEntryInfoSize
invoke RasEnumEntries, 0, 0, edi, addr dwEntryInfoSize, addr cEntries
.endif
.if eax == 0
xor esi, esi
.while esi < sizeof buffer
.break .if [edi][esi].dwSize != sizeof RASENTRYNAMEA_
invoke lstrcat, addr buffer, addr [edi][esi].szEntryName
invoke lstrcat, addr buffer, addr NewLine
add esi, sizeof RASENTRYNAMEA_
.endw
invoke MessageBox, NULL, addr buffer, addr szCaption, MB_OK
.endif
assume edi:nothing
invoke HeapFree, hHeap, 0, edi
ret
PhoneBook ENDP
start:
invoke PhoneBook
invoke ExitProcess, 0
ret
end start
???? ??????? Four-F
It is a very detailed answer
Thank you very much !
It is a very detailed answer
Thank you very much !
??????????.
PS: "???? ???????" shoulb be "??????? ???????" :)
PS: "???? ???????" shoulb be "??????? ???????" :)
The #pragma directives in the .H files force DWORD alignment on Win32.
Now clear.