Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added CoTaskAllocMemory to Ole32 #333

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Features
--------
* Updated AIX natives and build - [@twall](https://github.com/twall).
* [#290](https://github.com/twall/jna/pull/290): Improved the stacktrace for the exceptions thrown by `com.sun.jna.Structure` - [@ebourg](https://github.com/ebourg).
* [#333](https://github.com/twall/jna/pull/333): Added `CoTaskMemAlloc`, `CoTaskMemRealloc` and `CoTaskMemFree` to `com.sun.jna.platform.win32.Ole32` - [@msteiger](https://github.com/msteiger).

Bug Fixes
---------
Expand Down
53 changes: 53 additions & 0 deletions contrib/platform/src/com/sun/jna/platform/win32/Ole32.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.WString;
import com.sun.jna.platform.win32.BaseTSD.SIZE_T;
import com.sun.jna.platform.win32.Guid.CLSID;
import com.sun.jna.platform.win32.Guid.GUID;
import com.sun.jna.platform.win32.WinDef.LPVOID;
Expand Down Expand Up @@ -214,4 +215,56 @@ HRESULT CoCreateInstance(GUID rclsid, Pointer pUnkOuter, int dwClsContext,
*/
HRESULT CLSIDFromString(WString lpsz, CLSID.ByReference pclsid);

/**
* Allocates a block of task memory in the same way that IMalloc::Alloc does. CoTaskMemAlloc uses the default
* allocator to allocate a memory block in the same way that IMalloc::Alloc does. It is not necessary to call the
* CoGetMalloc function before calling CoTaskMemAlloc.
* <br/><br/>The initial contents of the returned memory block are
* undefined - there is no guarantee that the block has been initialized. The allocated block may be larger than cb
* bytes because of the space required for alignment and for maintenance information.
* <br/><br/>
* If cb is 0, CoTaskMemAlloc
* allocates a zero-length item and returns a valid pointer to that item. If there is insufficient memory available,
* CoTaskMemAlloc returns NULL. Applications should always check the return value from this function, even when
* requesting small amounts of memory, because there is no guarantee that the memory will be allocated.
* @param cb The size of the memory block to be allocated, in bytes.
* @return If the function succeeds, it returns the allocated memory block. Otherwise, it returns NULL.
*/
LPVOID CoTaskMemAlloc(SIZE_T cb);

/**
* Changes the size of a previously allocated block of task memory. This function changes the size of a previously
* allocated memory block in the same way that IMalloc::Realloc does. It is not necessary to call the CoGetMalloc
* function to get a pointer to the OLE allocator before calling CoTaskMemRealloc.
* <br/><br/>
* The pv parameter points to the
* beginning of the memory block. If pv is NULL, CoTaskMemRealloc allocates a new memory block in the same way as
* the CoTaskMemAlloc function. If pv is not NULL, it should be a pointer returned by a prior call to
* CoTaskMemAlloc.
* <br/><br>
* The cb parameter specifies the size of the new block. The contents of the block are unchanged up
* to the shorter of the new and old sizes, although the new block can be in a different location. Because the new
* block can be in a different memory location, the pointer returned by CoTaskMemRealloc is not guaranteed to be the
* pointer passed through the pv argument. If pv is not NULL and cb is 0, then the memory pointed to by pv is freed.
* <br/><br/>
* CoTaskMemRealloc returns a void pointer to the reallocated (and possibly moved) memory block. The return value is
* NULL if the size is 0 and the buffer argument is not NULL, or if there is not enough memory available to expand
* the block to the specified size. In the first case, the original block is freed; in the second case, the original
* block is unchanged. The storage space pointed to by the return value is guaranteed to be suitably aligned for
* storage of any type of object. To get a pointer to a type other than void, use a type cast on the return value.
* @param pv A pointer to the memory block to be reallocated. This parameter can be NULL.
* @param cb The size of the memory block to be reallocated, in bytes. This parameter can be 0.
* @return If the function succeeds, it returns the reallocated memory block. Otherwise, it returns NULL.
*/
LPVOID CoTaskMemRealloc(LPVOID pv, SIZE_T cb);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs tests.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignore me.

You might want to split the tests, write one for just alloc, another for realloc, so it's clear that we cover things. Don't feel strongly about it, but a bit of redundancy in tests is OK so that we can catch the case where alloc works but realloc fails.


/**
* Frees a block of task memory previously allocated through a call to the {@link #CoTaskMemAlloc} or
* {@link #CoTaskMemRealloc} function. The function uses the default OLE allocator. The number of bytes
* freed equals the number of bytes that were originally allocated or reallocated. After the call, the memory block
* pointed to by pv is invalid and can no longer be used.
* @param pv A pointer to the memory block to be freed. If this parameter is NULL, the function has no effect.
*/
void CoTaskMemFree(LPVOID pv);

}
22 changes: 22 additions & 0 deletions contrib/platform/test/com/sun/jna/platform/win32/Ole32Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@

import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.BaseTSD.SIZE_T;
import com.sun.jna.platform.win32.Guid.GUID;
import com.sun.jna.platform.win32.WinDef.LPVOID;
import com.sun.jna.platform.win32.WinNT.HRESULT;
import com.sun.jna.ptr.PointerByReference;

Expand Down Expand Up @@ -106,4 +108,24 @@ public final void testCLSIDFromProgID() {
assertEquals(WinError.S_OK, Ole32.INSTANCE.CLSIDFromProgID("jpegfile", clsid));
assertEquals("{25336920-03F9-11CF-8FD0-00AA00686F13}", clsid.toGuidString());
}

public void testCoTaskMemAlloc() {
LPVOID ptr = Ole32.INSTANCE.CoTaskMemAlloc(new SIZE_T(256));

assertTrue(ptr.longValue() != 0);

Ole32.INSTANCE.CoTaskMemFree(ptr);
}

public void testCoTaskMemRealloc() {
LPVOID ptr = Ole32.INSTANCE.CoTaskMemAlloc(new SIZE_T(256));

assertTrue(ptr.longValue() != 0);

ptr = Ole32.INSTANCE.CoTaskMemRealloc(ptr, new SIZE_T(128));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is redundant with above, except for the size, no? And you leak the first one. You should just remove it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh sorry, didn't see it's a Realloc ....


assertTrue(ptr.longValue() != 0);

Ole32.INSTANCE.CoTaskMemFree(ptr);
}
}