I am trying to convert a c++ function to assembler. I am having a problem with a globalalloc statement being typcast in c++. I don't know how to do it in assember or even if I should. Here is the section of code: // Allocate memory for NETRESOURCE structures. lpnrLocal = (LPNETRESOURCE) GlobalAlloc(GPTR, cbBuffer); dwResultEnum = WNetEnumResource(hEnum, // resource handle &cEntries, // defined locally as 0xFFFFFFFF lpnrLocal, // LPNETRESOURCE &cbBuffer); // buffer size The LPNETRESOURCE is a structure. I have tested the code under c++ and it works fine. Here is the code as I have translated it: invoke GlobalAlloc,GPTR, cbBuffer mov lhNetr,eax invoke WNetEnumResource,hEnum,Addr cEntries, Addr lhNetr,Addr cbBuffer mov dwResultEnum, eax The example code comes directly out of the Win32 help file. Thanks for any help. Raeldin
Posted on 2000-11-15 16:52:00 by Raeldin
Sorry....I am getting the error: error A2022: instruction operands must be the same size Not sure what to do about it. Thanks.....
Posted on 2000-11-15 17:05:00 by Raeldin
First, I'd like to point out an unuseful pointer conversion: invoke WNetEnumResource,hEnum,ADDR cEntries,ADDR lhNetr,ADDR cbBuffer should become: invoke WNetEnumResource,hEnum,ADDR cEntries,lhNetr,ADDR cbBuffer Aside from that, the code seems fine to me. Are you sure the line number from the assembler is in that chunk? (Note: Sometimes the assembler is a few lines off when it displays the erroring line.)
Posted on 2000-11-15 17:47:00 by Racso
I have changed the pointer converstion. I then get the message: error A2114: INVOKE argument type mismatch : argument : 3 in addition to the other error. As for being the correct line, I comment out the line in question and don't get the error. I just tried it and the line that is giving me the same size error is mov lhNetr,eax This makes sense as the lhNetr is a structure. I am confused on the pointer part here. lhNetr is defined as LOCAL lhNetr:NETRESOURCE does that automatically make it a pointer? or do I need another variable. Thanks
Posted on 2000-11-15 18:01:00 by Raeldin
Well, what's happening is that, instead of using a pointer (like in the C/C++ version), you're using an actual structure. (For all Windows definitions, anything begining with LP means it's a Long Pointer.) You'll need to rectify this situation however you deem appropriate. The simplest solution that I can think of would be to replace NETRESOURCE with DWORD. Ie: .data lhNetr dd 0 invoke GlobalAlloc,GPTR,cbBuffer mov lhNetr,eax However, there are other, more innovative solutions available at your disposal. Don't worry about it not being the -exact- variable type as it was in C. To Assembly, numbers are numbers...period. Typecasting is only very rarely needed. :)
Posted on 2000-11-15 19:09:00 by Racso
I thought thats the way it worked but seems like I tried it. I will try it tomorrow and see what happens... Thanks
Posted on 2000-11-15 20:39:00 by Raeldin
Here's how to use a LOCAL struct. First, you defined: LOCAL lhNetr:NETRESOURCE This allocates 8 dwords of storage on the stack, since a NETRESOURCE looks like this: NETRESOURCE STRUCT dwScope DWORD ? dwType DWORD ? dwDisplayType DWORD ? dwUsage DWORD ? lpLocalName DWORD ? lpRemoteName DWORD ? lpComment DWORD ? lpProvider DWORD ? NETRESOURCE ENDS So, now is should be obvious why this line is wrong: mov lhNetr,eax hlNetr is 8 dwords big, eax is just 1 dword. Thats the size mismatch. So.... thats sonme background, now onto the WNetEnumResource API function: DWORD WNetEnumResource (HANDLE hEnum,LPDWORD lpcCount, LPVOID lpBuffer, LPDWORD lpBufferSize); Now keep in mind if you request N items by lpcCount, you need a buffer N * 4 * 8 bytes long, as each item is 4 * 8 bytes (8 dwords) big. First complication: You're asking for FFFFFFFF (-1) items, this is the code for "SEND EM ALL." But you don't know how many you're going to get, right? No problem. If you pass WNetEnumResource a buffer of zero length (or smaller then 8 bytes), it will return the necesary buffer size. So, the scheme to use this function would be somethihng like this psudocode: LOCAL BufSize:DWORD, pBuffer:DWORD ; get size of buffer ; hEnum from somewhere else invoke WNetEnumResource, hEnum, -1, NULL, ADDR BufSize ; alloc this bufer ; must first know hHeap (from GetProcessHeap) invoke HeapAlloc, hHeap, NULL, BufSize mov pBuffer, eax ; now fill buffer invoke WNetEnumResource, hEnum, -1, pBuffer, ADDR BufSize ; now to access these Item elements mov ecx, pBuffer mov eax, (NETRESOURCE PTR ).dwScope ; use this item's Scope now ; look at next item add ecx, SIZEOF NETRESOURCE mov eax, (NETRESOURCE PTR ).dwScope ; and so on... :lastly invoke HeapFree, hHeap, NULL, pBuffer
Posted on 2000-11-16 21:42:00 by TTom
Oops.. forgot to zero the buffer size. Add this after the LOCAL in the psudocode: xor eax, eax mov BufSize, eax
Posted on 2000-11-16 21:45:00 by TTom
That worked thanks TTom
Posted on 2000-11-17 13:43:00 by Raeldin