Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
DRIVER_INFO_2
Message
Information générale
Forum:
Visual FoxPro
Catégorie:
Fonctions Windows API
Titre:
Divers
Thread ID:
00186207
Message ID:
00186556
Vues:
14
>> You can allocate the structure itself in a VFP string, but the pointers to > strings need to be allocated in memory outside the VFP memory space. My
>> CLSHEAP class could handle the allocations, as could Paul Tatavu's POINTERS class. Using CLSHEAP:
>[snip...]
>> When you've finished, invoke oHeap.Dealloc against whatever you've finished with; releasing oHeap (ie oheap = NULL) will release all remain allocs
>> and release the heap owned by the object.
>
>Ed,
> Thanks for the sample code. I downloaded your CLSHEAP.PRG file and successfully incorporated your sample into my call to AddPrinterDriver. It seems, however, that every time I call AddPrinterDriver it returns true no matter what I specify for the print driver. Here's the code that I'm using:
>
>---
>FUNCTION InstallGenericDriver
>
>LOCAL lcMyNameString,lcMyEnvString,lcPath,lcFilename,lcConfigFilename
>
>#DEFINE SizeOfName 2
>#DEFINE SizeOfEnvironment 2
>#DEFINE SizeOfDriverPath 2
>#DEFINE SizeOfFilename 2
>#DEFINE SizeOfConfigFilename 2
>
>DECLARE INTEGER AddPrinterDriver IN WINSPOOL.DRV ;
> STRING @ lpName, ;
> INTEGER Level, ;
> STRING @ lpDriverInfo
>
>SET PROCEDURE TO CLSHEAP.PRG ADDITIVE
>
>lnVersion = 4.00
>lcMyNameString = "Generic"
>lcMyEnvString = ""
>lcPath = "TTY.DRV"
>lcFilename = "TTY.DRV"
>lcConfigFileName = ""
>
>oHeap = CREATEOBJ('Heap')
>lnNameBuffer = oHeap.Alloc(SizeOfName)
>oHeap.CopyTo(lnNameBuffer,lcMyNameString+CHR(0))

Here's part of your problem - the size of the string to allocate should be at least 1 greater than the length of the VFP variable you're passing - the character string + a null terminator (CHR(0)). If you read CLSHEAP, the CopyTo method copies the smaller of the number of characters in the allocated buffer and the length of the string being copied. You might want to create a function (or subclass Heap to add a method) with the following behavior:

FUNCTION AllocAndCopyString
LPARAMETER cStringToCopy, oHeapObj
LOCAL nSizeToAlloc, nAllocPtr
nSizeToAlloc = LEN(cStringToCopy) + 1
nAllocPtr = oHeapObj.Alloc(nSizeToAlloc)
oHeapObj.CopyTo(nAllocPtr,cStringToCopy + CHR(0))
RETURN nAllocPtr

Obviously, if you create a method, you can use this as the object reference instead of passing it explicitly.

FWIW, I'll probably add this method and something that copies a binary string in the next version of CLSHEAP. There are other things going in as well to allocate and deallocate NetAPI buffers, which are needed for some API calls, but that's probably a week or two from release at best. And I still need to find time to write some decent docs for it, too.

I'm afraid I don't use this API call myself in any code at the moment, so I'm not really sure how much help i can offer on the API call itself.

>lnEnvBuffer = oHeap.Alloc(SizeOfEnvironment)
>oHeap.CopyTo(lnEnvBuffer,lcMyEnvString + CHR(0))
>lnDriverPath = oHeap.Alloc(SizeOfDriverPath)
>oHeap.CopyTo(lnDriverPath,lcPath + CHR(0))
>lnFileBuff = oHeap.Alloc(SizeOfFilename)
>oHeap.CopyTo(lnFileBuff,lcFilename + CHR(0))
>lnConfig = oHeap.Alloc(SizeOfConfigFilename)
>oHeap.CopyTo(lnConfig,lcConfigFilename + CHR(0))
>lcDriverInfo2 = NumTODWORD(lnVersion) + ;
> NumToDWORD(lnNameBuffer) + ;
> NumToDWORD(lnEnvBuffer) + ;
> NumToDWORD(lnDriverPath) + ;
> NumTODWORD(lnFileBuff) + ;
> NumToDWORD(lnConfig)
>
>lnRetVal = AddPrinterDriver("", 2, @lcDriverInfo2)
>
>messagebox("AddPrinterDriver returned " + iif(lnRetVal <> 0, "TRUE", "FALSE"), 48, "")
>
>RETURN lnRetVal
>
>oHeap.Dealloc()

Another problem - you need to Dealloc() a pointer - you could release the heap by assigning a null to the object variable, which deallocs everything and releases the heap at the same time. IOW, you'd say:

oHeap.DeAlloc(lnFileBuff)

to release the allocation pointed to by lnFileBuff.

There are lots of quirky little tricks to minimize the number of Alloc invocations; the pointer returned from alloc is a base pointer, and you can compute substring positions within a buffer and add the base pointer to them. For example, the following builds three pointers from a single alloc (assume that oHeap is an existing heap)

nBasePtr = oHeap.Alloc(500) && allocate 500 bytes
cString = 'First argument' + CHR(0)
nSecondStartsAt = nBasePtr + LEN(cString)
cString = cString + 'Second thing' + CHR(0)
nLastOneStartsAt = nBasePtr + LEN(cString)
cString = cString + NumTODWORD(42) && answer to everything as a DWORD
oHeap.CopyTo(nBasePtr,cString) && copy everything into place

You now have a single allocation with three pointers to parts of the allocated block of memory. Welcome to the world of roll your own memory management...

>
>ENDFUNC
>---
>
>I have a sinking suspicion that my problem is coming from the definitions made inside of lcDriverInfo2. For those who have tried installing printer drivers before, are those the correct filenames?
>
>Also, another quick question. If the driver is successfully installed, will it present itself inside of WIN.INI in the Devices and PrinterPorts sections?
>
>Thanks in advance.
EMail: EdR@edrauh.com
"See, the sun is going down..."
"No, the horizon is moving up!"
- Firesign Theater


NT and Win2K FAQ .. cWashington WSH/ADSI/WMI site
MS WSH site ........... WSH FAQ Site
Wrox Press .............. Win32 Scripting Journal
eSolutions Services, LLC

The Surgeon General has determined that prolonged exposure to the Windows Script Host may be addictive to laboratory mice and codemonkeys
Précédent
Répondre
Fil
Voir

Click here to load this message in the networking platform