Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
6c5e8722
Commit
6c5e8722
authored
May 15, 2003
by
Steven Edwards
Committed by
Alexandre Julliard
May 15, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Separate Win16 and Win32 implementations in memlockbytes.
parent
6d1a1d49
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
582 additions
and
541 deletions
+582
-541
Makefile.in
dlls/ole32/Makefile.in
+3
-1
memlockbytes.c
dlls/ole32/memlockbytes.c
+0
-540
memlockbytes16.c
dlls/ole32/memlockbytes16.c
+579
-0
No files found.
dlls/ole32/Makefile.in
View file @
6c5e8722
...
...
@@ -45,7 +45,9 @@ C_SRCS = \
storage.c
\
storage32.c
C_SRCS16
=
ole2nls.c
C_SRCS16
=
\
memlockbytes16.c
\
ole2nls.c
RC_SRCS
=
ole32res.rc version.rc
...
...
dlls/ole32/memlockbytes.c
View file @
6c5e8722
...
...
@@ -623,543 +623,3 @@ HRESULT WINAPI HGLOBALLockBytesImpl_Stat(
return
S_OK
;
}
/******************************************************************************
* HGLOBALLockBytesImpl16 definition.
*
* This class imlements the ILockBytes inteface and represents a byte array
* object supported by an HGLOBAL pointer.
*/
struct
HGLOBALLockBytesImpl16
{
/*
* Needs to be the first item in the stuct
* since we want to cast this in an ILockBytes pointer
*/
ICOM_VFIELD
(
ILockBytes16
);
ULONG
ref
;
/*
* Support for the LockBytes object
*/
HGLOBAL16
supportHandle
;
/*
* This flag is TRUE if the HGLOBAL is destroyed when the object
* is finally released.
*/
BOOL
deleteOnRelease
;
/*
* Helper variable that contains the size of the byte array
*/
ULARGE_INTEGER
byteArraySize
;
};
typedef
struct
HGLOBALLockBytesImpl16
HGLOBALLockBytesImpl16
;
HGLOBALLockBytesImpl16
*
HGLOBALLockBytesImpl16_Construct
(
HGLOBAL16
hGlobal
,
BOOL16
fDeleteOnRelease
);
void
HGLOBALLockBytesImpl16_Destroy
(
HGLOBALLockBytesImpl16
*
This
);
HRESULT
WINAPI
HGLOBALLockBytesImpl16_QueryInterface
(
ILockBytes16
*
iface
,
REFIID
riid
,
/* [in] */
void
**
ppvObject
);
/* [iid_is][out] */
ULONG
WINAPI
HGLOBALLockBytesImpl16_AddRef
(
ILockBytes16
*
iface
);
ULONG
WINAPI
HGLOBALLockBytesImpl16_Release
(
ILockBytes16
*
iface
);
HRESULT
WINAPI
HGLOBALLockBytesImpl16_ReadAt
(
ILockBytes16
*
iface
,
ULARGE_INTEGER
ulOffset
,
/* [in] */
void
*
pv
,
/* [length_is][size_is][out] */
ULONG
cb
,
/* [in] */
ULONG
*
pcbRead
);
/* [out] */
HRESULT
WINAPI
HGLOBALLockBytesImpl16_WriteAt
(
ILockBytes16
*
iface
,
ULARGE_INTEGER
ulOffset
,
/* [in] */
const
void
*
pv
,
/* [size_is][in] */
ULONG
cb
,
/* [in] */
ULONG
*
pcbWritten
);
/* [out] */
HRESULT
WINAPI
HGLOBALLockBytesImpl16_Flush
(
ILockBytes16
*
iface
);
HRESULT
WINAPI
HGLOBALLockBytesImpl16_SetSize
(
ILockBytes16
*
iface
,
ULARGE_INTEGER
libNewSize
);
/* [in] */
HRESULT
WINAPI
HGLOBALLockBytesImpl16_LockRegion
(
ILockBytes16
*
iface
,
ULARGE_INTEGER
libOffset
,
/* [in] */
ULARGE_INTEGER
cb
,
/* [in] */
DWORD
dwLockType
);
/* [in] */
HRESULT
WINAPI
HGLOBALLockBytesImpl16_UnlockRegion
(
ILockBytes16
*
iface
,
ULARGE_INTEGER
libOffset
,
/* [in] */
ULARGE_INTEGER
cb
,
/* [in] */
DWORD
dwLockType
);
/* [in] */
HRESULT
WINAPI
HGLOBALLockBytesImpl16_Stat
(
ILockBytes16
*
iface
,
STATSTG16
*
pstatstg
,
/* [out] */
DWORD
grfStatFlag
);
/* [in] */
/******************************************************************************
*
* HGLOBALLockBytesImpl16 implementation
*
*/
/******************************************************************************
* This is the constructor for the HGLOBALLockBytesImpl16 class.
*
* Params:
* hGlobal - Handle that will support the stream. can be NULL.
* fDeleteOnRelease - Flag set to TRUE if the HGLOBAL16 will be released
* when the IStream object is destroyed.
*/
HGLOBALLockBytesImpl16
*
HGLOBALLockBytesImpl16_Construct
(
HGLOBAL16
hGlobal
,
BOOL16
fDeleteOnRelease
)
{
HGLOBALLockBytesImpl16
*
newLockBytes
;
static
ICOM_VTABLE
(
ILockBytes16
)
vt16
;
static
SEGPTR
msegvt16
;
HMODULE16
hcomp
=
GetModuleHandle16
(
"OLE2"
);
TRACE
(
"(%x,%d)
\n
"
,
hGlobal
,
fDeleteOnRelease
);
newLockBytes
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
HGLOBALLockBytesImpl16
));
if
(
newLockBytes
==
NULL
)
return
NULL
;
/*
* Set up the virtual function table and reference count.
*/
if
(
!
msegvt16
)
{
#define VTENT(x) vt16.x = (void*)GetProcAddress16(hcomp,"HGLOBALLockBytesImpl16_"#x);assert(vt16.x)
VTENT
(
QueryInterface
);
VTENT
(
AddRef
);
VTENT
(
Release
);
VTENT
(
ReadAt
);
VTENT
(
WriteAt
);
VTENT
(
Flush
);
VTENT
(
SetSize
);
VTENT
(
LockRegion
);
VTENT
(
UnlockRegion
);
#undef VTENT
msegvt16
=
MapLS
(
&
vt16
);
}
newLockBytes
->
lpVtbl
=
(
ICOM_VTABLE
(
ILockBytes16
)
*
)
msegvt16
;
newLockBytes
->
ref
=
0
;
/*
* Initialize the support.
*/
newLockBytes
->
supportHandle
=
hGlobal
;
newLockBytes
->
deleteOnRelease
=
fDeleteOnRelease
;
/*
* This method will allocate a handle if one is not supplied.
*/
if
(
newLockBytes
->
supportHandle
==
0
)
newLockBytes
->
supportHandle
=
GlobalAlloc16
(
GMEM_MOVEABLE
|
GMEM_NODISCARD
,
0
);
/*
* Initialize the size of the array to the size of the handle.
*/
newLockBytes
->
byteArraySize
.
s
.
HighPart
=
0
;
newLockBytes
->
byteArraySize
.
s
.
LowPart
=
GlobalSize16
(
newLockBytes
->
supportHandle
);
return
(
HGLOBALLockBytesImpl16
*
)
MapLS
(
newLockBytes
);
}
/******************************************************************************
* This is the destructor of the HGLOBALStreamImpl class.
*
* This method will clean-up all the resources used-up by the given
* HGLOBALLockBytesImpl16 class. The pointer passed-in to this function will be
* freed and will not be valid anymore.
*/
void
HGLOBALLockBytesImpl16_Destroy
(
HGLOBALLockBytesImpl16
*
This
)
{
TRACE
(
"()
\n
"
);
/*
* Release the HGlobal if the constructor asked for that.
*/
if
(
This
->
deleteOnRelease
)
{
GlobalFree16
(
This
->
supportHandle
);
This
->
supportHandle
=
0
;
}
/*
* Finally, free the memory used-up by the class.
*/
HeapFree
(
GetProcessHeap
(),
0
,
This
);
}
/******************************************************************************
* This implements the IUnknown method QueryInterface for this
* class
*/
HRESULT
WINAPI
HGLOBALLockBytesImpl16_QueryInterface
(
ILockBytes16
*
iface
,
/* [in] SEGPTR */
REFIID
riid
,
/* [in] */
void
**
ppvObject
)
/* [iid_is][out] (ptr to SEGPTR!) */
{
HGLOBALLockBytesImpl16
*
const
This
=
(
HGLOBALLockBytesImpl16
*
)
MapSL
((
SEGPTR
)
iface
);
TRACE
(
"(%p,%s,%p)
\n
"
,
iface
,
debugstr_guid
(
riid
),
ppvObject
);
/*
* Perform a sanity check on the parameters.
*/
if
(
ppvObject
==
0
)
return
E_INVALIDARG
;
/*
* Initialize the return parameter.
*/
*
ppvObject
=
0
;
/*
* Compare the riid with the interface IDs implemented by this object.
*/
if
(
!
memcmp
(
&
IID_IUnknown
,
riid
,
sizeof
(
IID_IUnknown
))
||
!
memcmp
(
&
IID_ILockBytes
,
riid
,
sizeof
(
IID_ILockBytes
))
)
*
ppvObject
=
(
void
*
)
iface
;
/*
* Check that we obtained an interface.
*/
if
((
*
ppvObject
)
==
0
)
return
E_NOINTERFACE
;
/*
* Query Interface always increases the reference count by one when it is
* successful
*/
HGLOBALLockBytesImpl16_AddRef
((
ILockBytes16
*
)
This
);
return
S_OK
;
}
/******************************************************************************
* This implements the IUnknown method AddRef for this
* class
*/
ULONG
WINAPI
HGLOBALLockBytesImpl16_AddRef
(
ILockBytes16
*
iface
)
{
HGLOBALLockBytesImpl16
*
const
This
=
(
HGLOBALLockBytesImpl16
*
)
iface
;
TRACE
(
"(%p)
\n
"
,
This
);
This
->
ref
++
;
return
This
->
ref
;
}
/******************************************************************************
* This implements the IUnknown method Release for this
* class
*/
ULONG
WINAPI
HGLOBALLockBytesImpl16_Release
(
ILockBytes16
*
iface
)
{
HGLOBALLockBytesImpl16
*
const
This
=
(
HGLOBALLockBytesImpl16
*
)
iface
;
ULONG
newRef
;
TRACE
(
"(%p)
\n
"
,
This
);
This
->
ref
--
;
newRef
=
This
->
ref
;
/*
* If the reference count goes down to 0, perform suicide.
*/
if
(
newRef
==
0
)
HGLOBALLockBytesImpl16_Destroy
(
This
);
return
newRef
;
}
/******************************************************************************
* This method is part of the ILockBytes interface.
*
* It reads a block of information from the byte array at the specified
* offset.
*
* See the documentation of ILockBytes for more info.
*/
HRESULT
WINAPI
HGLOBALLockBytesImpl16_ReadAt
(
ILockBytes16
*
iface
,
ULARGE_INTEGER
ulOffset
,
/* [in] */
void
*
pv
,
/* [length_is][size_is][out] */
ULONG
cb
,
/* [in] */
ULONG
*
pcbRead
)
/* [out] */
{
HGLOBALLockBytesImpl16
*
const
This
=
(
HGLOBALLockBytesImpl16
*
)
iface
;
void
*
supportBuffer
;
ULONG
bytesReadBuffer
=
0
;
ULONG
bytesToReadFromBuffer
;
TRACE
(
"(%p,%ld,%p,%ld,%p)
\n
"
,
This
,
ulOffset
.
s
.
LowPart
,
pv
,
cb
,
pcbRead
);
/*
* If the caller is not interested in the number of bytes read,
* we use another buffer to avoid "if" statements in the code.
*/
if
(
pcbRead
==
0
)
pcbRead
=
&
bytesReadBuffer
;
/*
* Make sure the offset is valid.
*/
if
(
ulOffset
.
s
.
LowPart
>
This
->
byteArraySize
.
s
.
LowPart
)
return
E_FAIL
;
/*
* Using the known size of the array, calculate the number of bytes
* to read.
*/
bytesToReadFromBuffer
=
min
(
This
->
byteArraySize
.
s
.
LowPart
-
ulOffset
.
s
.
LowPart
,
cb
);
/*
* Lock the buffer in position and copy the data.
*/
supportBuffer
=
GlobalLock16
(
This
->
supportHandle
);
memcpy
(
pv
,
(
char
*
)
supportBuffer
+
ulOffset
.
s
.
LowPart
,
bytesToReadFromBuffer
);
/*
* Return the number of bytes read.
*/
*
pcbRead
=
bytesToReadFromBuffer
;
/*
* Cleanup
*/
GlobalUnlock16
(
This
->
supportHandle
);
/*
* The function returns S_OK if the specified number of bytes were read
* or the end of the array was reached.
* It returns STG_E_READFAULT if the number of bytes to read does not equal
* the number of bytes actually read.
*/
if
(
*
pcbRead
==
cb
)
return
S_OK
;
return
STG_E_READFAULT
;
}
/******************************************************************************
* This method is part of the ILockBytes interface.
*
* It writes the specified bytes at the specified offset.
* position. If the array is too small, it will be resized.
*
* See the documentation of ILockBytes for more info.
*/
HRESULT
WINAPI
HGLOBALLockBytesImpl16_WriteAt
(
ILockBytes16
*
iface
,
ULARGE_INTEGER
ulOffset
,
/* [in] */
const
void
*
pv
,
/* [size_is][in] */
ULONG
cb
,
/* [in] */
ULONG
*
pcbWritten
)
/* [out] */
{
HGLOBALLockBytesImpl16
*
const
This
=
(
HGLOBALLockBytesImpl16
*
)
iface
;
void
*
supportBuffer
;
ULARGE_INTEGER
newSize
;
ULONG
bytesWritten
=
0
;
TRACE
(
"(%p,%ld,%p,%ld,%p)
\n
"
,
This
,
ulOffset
.
s
.
LowPart
,
pv
,
cb
,
pcbWritten
);
/*
* If the caller is not interested in the number of bytes written,
* we use another buffer to avoid "if" statements in the code.
*/
if
(
pcbWritten
==
0
)
pcbWritten
=
&
bytesWritten
;
if
(
cb
==
0
)
return
S_OK
;
newSize
.
s
.
HighPart
=
0
;
newSize
.
s
.
LowPart
=
ulOffset
.
s
.
LowPart
+
cb
;
/*
* Verify if we need to grow the stream
*/
if
(
newSize
.
s
.
LowPart
>
This
->
byteArraySize
.
s
.
LowPart
)
{
/* grow stream */
if
(
HGLOBALLockBytesImpl16_SetSize
(
iface
,
newSize
)
==
STG_E_MEDIUMFULL
)
return
STG_E_MEDIUMFULL
;
}
/*
* Lock the buffer in position and copy the data.
*/
supportBuffer
=
GlobalLock16
(
This
->
supportHandle
);
memcpy
((
char
*
)
supportBuffer
+
ulOffset
.
s
.
LowPart
,
pv
,
cb
);
/*
* Return the number of bytes written.
*/
*
pcbWritten
=
cb
;
/*
* Cleanup
*/
GlobalUnlock16
(
This
->
supportHandle
);
return
S_OK
;
}
/******************************************************************************
* This method is part of the ILockBytes interface.
*
* See the documentation of ILockBytes for more info.
*/
HRESULT
WINAPI
HGLOBALLockBytesImpl16_Flush
(
ILockBytes16
*
iface
)
{
TRACE
(
"(%p)
\n
"
,
iface
);
return
S_OK
;
}
/******************************************************************************
* This method is part of the ILockBytes interface.
*
* It will change the size of the byte array.
*
* See the documentation of ILockBytes for more info.
*/
HRESULT
WINAPI
HGLOBALLockBytesImpl16_SetSize
(
ILockBytes16
*
iface
,
ULARGE_INTEGER
libNewSize
)
/* [in] */
{
HGLOBALLockBytesImpl16
*
const
This
=
(
HGLOBALLockBytesImpl16
*
)
iface
;
TRACE
(
"(%p,%ld)
\n
"
,
This
,
libNewSize
.
s
.
LowPart
);
/*
* As documented.
*/
if
(
libNewSize
.
s
.
HighPart
!=
0
)
return
STG_E_INVALIDFUNCTION
;
if
(
This
->
byteArraySize
.
s
.
LowPart
==
libNewSize
.
s
.
LowPart
)
return
S_OK
;
/*
* Re allocate the HGlobal to fit the new size of the stream.
*/
This
->
supportHandle
=
GlobalReAlloc16
(
This
->
supportHandle
,
libNewSize
.
s
.
LowPart
,
0
);
if
(
This
->
supportHandle
==
0
)
return
STG_E_MEDIUMFULL
;
This
->
byteArraySize
.
s
.
LowPart
=
libNewSize
.
s
.
LowPart
;
return
S_OK
;
}
/******************************************************************************
* This method is part of the ILockBytes interface.
*
* The global memory implementation of ILockBytes does not support locking.
*
* See the documentation of ILockBytes for more info.
*/
HRESULT
WINAPI
HGLOBALLockBytesImpl16_LockRegion
(
ILockBytes16
*
iface
,
ULARGE_INTEGER
libOffset
,
/* [in] */
ULARGE_INTEGER
cb
,
/* [in] */
DWORD
dwLockType
)
/* [in] */
{
return
STG_E_INVALIDFUNCTION
;
}
/******************************************************************************
* This method is part of the ILockBytes interface.
*
* The global memory implementation of ILockBytes does not support locking.
*
* See the documentation of ILockBytes for more info.
*/
HRESULT
WINAPI
HGLOBALLockBytesImpl16_UnlockRegion
(
ILockBytes16
*
iface
,
ULARGE_INTEGER
libOffset
,
/* [in] */
ULARGE_INTEGER
cb
,
/* [in] */
DWORD
dwLockType
)
/* [in] */
{
return
STG_E_INVALIDFUNCTION
;
}
/******************************************************************************
* This method is part of the ILockBytes interface.
*
* This method returns information about the current
* byte array object.
*
* See the documentation of ILockBytes for more info.
*/
HRESULT
WINAPI
HGLOBALLockBytesImpl16_Stat
(
ILockBytes16
*
iface
,
STATSTG16
*
pstatstg
,
/* [out] */
DWORD
grfStatFlag
)
/* [in] */
{
HGLOBALLockBytesImpl16
*
const
This
=
(
HGLOBALLockBytesImpl16
*
)
iface
;
memset
(
pstatstg
,
0
,
sizeof
(
STATSTG16
));
pstatstg
->
pwcsName
=
NULL
;
pstatstg
->
type
=
STGTY_LOCKBYTES
;
pstatstg
->
cbSize
=
This
->
byteArraySize
;
return
S_OK
;
}
/******************************************************************************
* CreateILockBytesOnHGlobal [OLE2.54]
*
* Creates an ILockBytes interface for a HGLOBAL handle.
*
* Params:
* hGlobal the global handle (16bit)
* fDeleteOnRelease delete handle on release.
* ppLkbyt pointer to ILockBytes interface.
*
* Returns:
* Staddard OLE error return codes.
*
*/
HRESULT
WINAPI
CreateILockBytesOnHGlobal16
(
HGLOBAL16
hGlobal
,
BOOL16
fDeleteOnRelease
,
/*SEGPTR**/
LPLOCKBYTES16
*
ppLkbyt
)
{
HGLOBALLockBytesImpl16
*
newLockBytes
;
/* SEGPTR */
newLockBytes
=
HGLOBALLockBytesImpl16_Construct
(
hGlobal
,
fDeleteOnRelease
);
if
(
newLockBytes
!=
NULL
)
return
HGLOBALLockBytesImpl16_QueryInterface
((
ILockBytes16
*
)
newLockBytes
,
&
IID_ILockBytes
,
(
void
**
)
ppLkbyt
);
return
E_OUTOFMEMORY
;
}
dlls/ole32/memlockbytes16.c
0 → 100644
View file @
6c5e8722
/*
* Global memory implementation of ILockBytes.
*
* Copyright 1999 Thuy Nguyen
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include <assert.h>
#include <string.h>
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
#include "wine/winbase16.h"
#include "objbase.h"
#include "ole2.h"
#include "winbase.h"
#include "winerror.h"
#include "ifs.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
ole
);
/******************************************************************************
* HGLOBALLockBytesImpl16 definition.
*
* This class imlements the ILockBytes inteface and represents a byte array
* object supported by an HGLOBAL pointer.
*/
struct
HGLOBALLockBytesImpl16
{
/*
* Needs to be the first item in the stuct
* since we want to cast this in an ILockBytes pointer
*/
ICOM_VFIELD
(
ILockBytes16
);
ULONG
ref
;
/*
* Support for the LockBytes object
*/
HGLOBAL16
supportHandle
;
/*
* This flag is TRUE if the HGLOBAL is destroyed when the object
* is finally released.
*/
BOOL
deleteOnRelease
;
/*
* Helper variable that contains the size of the byte array
*/
ULARGE_INTEGER
byteArraySize
;
};
typedef
struct
HGLOBALLockBytesImpl16
HGLOBALLockBytesImpl16
;
HGLOBALLockBytesImpl16
*
HGLOBALLockBytesImpl16_Construct
(
HGLOBAL16
hGlobal
,
BOOL16
fDeleteOnRelease
);
void
HGLOBALLockBytesImpl16_Destroy
(
HGLOBALLockBytesImpl16
*
This
);
HRESULT
WINAPI
HGLOBALLockBytesImpl16_QueryInterface
(
ILockBytes16
*
iface
,
REFIID
riid
,
/* [in] */
void
**
ppvObject
);
/* [iid_is][out] */
ULONG
WINAPI
HGLOBALLockBytesImpl16_AddRef
(
ILockBytes16
*
iface
);
ULONG
WINAPI
HGLOBALLockBytesImpl16_Release
(
ILockBytes16
*
iface
);
HRESULT
WINAPI
HGLOBALLockBytesImpl16_ReadAt
(
ILockBytes16
*
iface
,
ULARGE_INTEGER
ulOffset
,
/* [in] */
void
*
pv
,
/* [length_is][size_is][out] */
ULONG
cb
,
/* [in] */
ULONG
*
pcbRead
);
/* [out] */
HRESULT
WINAPI
HGLOBALLockBytesImpl16_WriteAt
(
ILockBytes16
*
iface
,
ULARGE_INTEGER
ulOffset
,
/* [in] */
const
void
*
pv
,
/* [size_is][in] */
ULONG
cb
,
/* [in] */
ULONG
*
pcbWritten
);
/* [out] */
HRESULT
WINAPI
HGLOBALLockBytesImpl16_Flush
(
ILockBytes16
*
iface
);
HRESULT
WINAPI
HGLOBALLockBytesImpl16_SetSize
(
ILockBytes16
*
iface
,
ULARGE_INTEGER
libNewSize
);
/* [in] */
HRESULT
WINAPI
HGLOBALLockBytesImpl16_LockRegion
(
ILockBytes16
*
iface
,
ULARGE_INTEGER
libOffset
,
/* [in] */
ULARGE_INTEGER
cb
,
/* [in] */
DWORD
dwLockType
);
/* [in] */
HRESULT
WINAPI
HGLOBALLockBytesImpl16_UnlockRegion
(
ILockBytes16
*
iface
,
ULARGE_INTEGER
libOffset
,
/* [in] */
ULARGE_INTEGER
cb
,
/* [in] */
DWORD
dwLockType
);
/* [in] */
HRESULT
WINAPI
HGLOBALLockBytesImpl16_Stat
(
ILockBytes16
*
iface
,
STATSTG16
*
pstatstg
,
/* [out] */
DWORD
grfStatFlag
);
/* [in] */
/******************************************************************************
*
* HGLOBALLockBytesImpl16 implementation
*
*/
/******************************************************************************
* This is the constructor for the HGLOBALLockBytesImpl16 class.
*
* Params:
* hGlobal - Handle that will support the stream. can be NULL.
* fDeleteOnRelease - Flag set to TRUE if the HGLOBAL16 will be released
* when the IStream object is destroyed.
*/
HGLOBALLockBytesImpl16
*
HGLOBALLockBytesImpl16_Construct
(
HGLOBAL16
hGlobal
,
BOOL16
fDeleteOnRelease
)
{
HGLOBALLockBytesImpl16
*
newLockBytes
;
static
ICOM_VTABLE
(
ILockBytes16
)
vt16
;
static
SEGPTR
msegvt16
;
HMODULE16
hcomp
=
GetModuleHandle16
(
"OLE2"
);
TRACE
(
"(%x,%d)
\n
"
,
hGlobal
,
fDeleteOnRelease
);
newLockBytes
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
HGLOBALLockBytesImpl16
));
if
(
newLockBytes
==
NULL
)
return
NULL
;
/*
* Set up the virtual function table and reference count.
*/
if
(
!
msegvt16
)
{
#define VTENT(x) vt16.x = (void*)GetProcAddress16(hcomp,"HGLOBALLockBytesImpl16_"#x);assert(vt16.x)
VTENT
(
QueryInterface
);
VTENT
(
AddRef
);
VTENT
(
Release
);
VTENT
(
ReadAt
);
VTENT
(
WriteAt
);
VTENT
(
Flush
);
VTENT
(
SetSize
);
VTENT
(
LockRegion
);
VTENT
(
UnlockRegion
);
#undef VTENT
msegvt16
=
MapLS
(
&
vt16
);
}
newLockBytes
->
lpVtbl
=
(
ICOM_VTABLE
(
ILockBytes16
)
*
)
msegvt16
;
newLockBytes
->
ref
=
0
;
/*
* Initialize the support.
*/
newLockBytes
->
supportHandle
=
hGlobal
;
newLockBytes
->
deleteOnRelease
=
fDeleteOnRelease
;
/*
* This method will allocate a handle if one is not supplied.
*/
if
(
newLockBytes
->
supportHandle
==
0
)
newLockBytes
->
supportHandle
=
GlobalAlloc16
(
GMEM_MOVEABLE
|
GMEM_NODISCARD
,
0
);
/*
* Initialize the size of the array to the size of the handle.
*/
newLockBytes
->
byteArraySize
.
s
.
HighPart
=
0
;
newLockBytes
->
byteArraySize
.
s
.
LowPart
=
GlobalSize16
(
newLockBytes
->
supportHandle
);
return
(
HGLOBALLockBytesImpl16
*
)
MapLS
(
newLockBytes
);
}
/******************************************************************************
* This is the destructor of the HGLOBALStreamImpl class.
*
* This method will clean-up all the resources used-up by the given
* HGLOBALLockBytesImpl16 class. The pointer passed-in to this function will be
* freed and will not be valid anymore.
*/
void
HGLOBALLockBytesImpl16_Destroy
(
HGLOBALLockBytesImpl16
*
This
)
{
TRACE
(
"()
\n
"
);
/*
* Release the HGlobal if the constructor asked for that.
*/
if
(
This
->
deleteOnRelease
)
{
GlobalFree16
(
This
->
supportHandle
);
This
->
supportHandle
=
0
;
}
/*
* Finally, free the memory used-up by the class.
*/
HeapFree
(
GetProcessHeap
(),
0
,
This
);
}
/******************************************************************************
* This implements the IUnknown method QueryInterface for this
* class
*/
HRESULT
WINAPI
HGLOBALLockBytesImpl16_QueryInterface
(
ILockBytes16
*
iface
,
/* [in] SEGPTR */
REFIID
riid
,
/* [in] */
void
**
ppvObject
)
/* [iid_is][out] (ptr to SEGPTR!) */
{
HGLOBALLockBytesImpl16
*
const
This
=
(
HGLOBALLockBytesImpl16
*
)
MapSL
((
SEGPTR
)
iface
);
TRACE
(
"(%p,%s,%p)
\n
"
,
iface
,
debugstr_guid
(
riid
),
ppvObject
);
/*
* Perform a sanity check on the parameters.
*/
if
(
ppvObject
==
0
)
return
E_INVALIDARG
;
/*
* Initialize the return parameter.
*/
*
ppvObject
=
0
;
/*
* Compare the riid with the interface IDs implemented by this object.
*/
if
(
!
memcmp
(
&
IID_IUnknown
,
riid
,
sizeof
(
IID_IUnknown
))
||
!
memcmp
(
&
IID_ILockBytes
,
riid
,
sizeof
(
IID_ILockBytes
))
)
*
ppvObject
=
(
void
*
)
iface
;
/*
* Check that we obtained an interface.
*/
if
((
*
ppvObject
)
==
0
)
return
E_NOINTERFACE
;
/*
* Query Interface always increases the reference count by one when it is
* successful
*/
HGLOBALLockBytesImpl16_AddRef
((
ILockBytes16
*
)
This
);
return
S_OK
;
}
/******************************************************************************
* This implements the IUnknown method AddRef for this
* class
*/
ULONG
WINAPI
HGLOBALLockBytesImpl16_AddRef
(
ILockBytes16
*
iface
)
{
HGLOBALLockBytesImpl16
*
const
This
=
(
HGLOBALLockBytesImpl16
*
)
iface
;
TRACE
(
"(%p)
\n
"
,
This
);
This
->
ref
++
;
return
This
->
ref
;
}
/******************************************************************************
* This implements the IUnknown method Release for this
* class
*/
ULONG
WINAPI
HGLOBALLockBytesImpl16_Release
(
ILockBytes16
*
iface
)
{
HGLOBALLockBytesImpl16
*
const
This
=
(
HGLOBALLockBytesImpl16
*
)
iface
;
ULONG
newRef
;
TRACE
(
"(%p)
\n
"
,
This
);
This
->
ref
--
;
newRef
=
This
->
ref
;
/*
* If the reference count goes down to 0, perform suicide.
*/
if
(
newRef
==
0
)
HGLOBALLockBytesImpl16_Destroy
(
This
);
return
newRef
;
}
/******************************************************************************
* This method is part of the ILockBytes interface.
*
* It reads a block of information from the byte array at the specified
* offset.
*
* See the documentation of ILockBytes for more info.
*/
HRESULT
WINAPI
HGLOBALLockBytesImpl16_ReadAt
(
ILockBytes16
*
iface
,
ULARGE_INTEGER
ulOffset
,
/* [in] */
void
*
pv
,
/* [length_is][size_is][out] */
ULONG
cb
,
/* [in] */
ULONG
*
pcbRead
)
/* [out] */
{
HGLOBALLockBytesImpl16
*
const
This
=
(
HGLOBALLockBytesImpl16
*
)
iface
;
void
*
supportBuffer
;
ULONG
bytesReadBuffer
=
0
;
ULONG
bytesToReadFromBuffer
;
TRACE
(
"(%p,%ld,%p,%ld,%p)
\n
"
,
This
,
ulOffset
.
s
.
LowPart
,
pv
,
cb
,
pcbRead
);
/*
* If the caller is not interested in the number of bytes read,
* we use another buffer to avoid "if" statements in the code.
*/
if
(
pcbRead
==
0
)
pcbRead
=
&
bytesReadBuffer
;
/*
* Make sure the offset is valid.
*/
if
(
ulOffset
.
s
.
LowPart
>
This
->
byteArraySize
.
s
.
LowPart
)
return
E_FAIL
;
/*
* Using the known size of the array, calculate the number of bytes
* to read.
*/
bytesToReadFromBuffer
=
min
(
This
->
byteArraySize
.
s
.
LowPart
-
ulOffset
.
s
.
LowPart
,
cb
);
/*
* Lock the buffer in position and copy the data.
*/
supportBuffer
=
GlobalLock16
(
This
->
supportHandle
);
memcpy
(
pv
,
(
char
*
)
supportBuffer
+
ulOffset
.
s
.
LowPart
,
bytesToReadFromBuffer
);
/*
* Return the number of bytes read.
*/
*
pcbRead
=
bytesToReadFromBuffer
;
/*
* Cleanup
*/
GlobalUnlock16
(
This
->
supportHandle
);
/*
* The function returns S_OK if the specified number of bytes were read
* or the end of the array was reached.
* It returns STG_E_READFAULT if the number of bytes to read does not equal
* the number of bytes actually read.
*/
if
(
*
pcbRead
==
cb
)
return
S_OK
;
return
STG_E_READFAULT
;
}
/******************************************************************************
* This method is part of the ILockBytes interface.
*
* It writes the specified bytes at the specified offset.
* position. If the array is too small, it will be resized.
*
* See the documentation of ILockBytes for more info.
*/
HRESULT
WINAPI
HGLOBALLockBytesImpl16_WriteAt
(
ILockBytes16
*
iface
,
ULARGE_INTEGER
ulOffset
,
/* [in] */
const
void
*
pv
,
/* [size_is][in] */
ULONG
cb
,
/* [in] */
ULONG
*
pcbWritten
)
/* [out] */
{
HGLOBALLockBytesImpl16
*
const
This
=
(
HGLOBALLockBytesImpl16
*
)
iface
;
void
*
supportBuffer
;
ULARGE_INTEGER
newSize
;
ULONG
bytesWritten
=
0
;
TRACE
(
"(%p,%ld,%p,%ld,%p)
\n
"
,
This
,
ulOffset
.
s
.
LowPart
,
pv
,
cb
,
pcbWritten
);
/*
* If the caller is not interested in the number of bytes written,
* we use another buffer to avoid "if" statements in the code.
*/
if
(
pcbWritten
==
0
)
pcbWritten
=
&
bytesWritten
;
if
(
cb
==
0
)
return
S_OK
;
newSize
.
s
.
HighPart
=
0
;
newSize
.
s
.
LowPart
=
ulOffset
.
s
.
LowPart
+
cb
;
/*
* Verify if we need to grow the stream
*/
if
(
newSize
.
s
.
LowPart
>
This
->
byteArraySize
.
s
.
LowPart
)
{
/* grow stream */
if
(
HGLOBALLockBytesImpl16_SetSize
(
iface
,
newSize
)
==
STG_E_MEDIUMFULL
)
return
STG_E_MEDIUMFULL
;
}
/*
* Lock the buffer in position and copy the data.
*/
supportBuffer
=
GlobalLock16
(
This
->
supportHandle
);
memcpy
((
char
*
)
supportBuffer
+
ulOffset
.
s
.
LowPart
,
pv
,
cb
);
/*
* Return the number of bytes written.
*/
*
pcbWritten
=
cb
;
/*
* Cleanup
*/
GlobalUnlock16
(
This
->
supportHandle
);
return
S_OK
;
}
/******************************************************************************
* This method is part of the ILockBytes interface.
*
* See the documentation of ILockBytes for more info.
*/
HRESULT
WINAPI
HGLOBALLockBytesImpl16_Flush
(
ILockBytes16
*
iface
)
{
TRACE
(
"(%p)
\n
"
,
iface
);
return
S_OK
;
}
/******************************************************************************
* This method is part of the ILockBytes interface.
*
* It will change the size of the byte array.
*
* See the documentation of ILockBytes for more info.
*/
HRESULT
WINAPI
HGLOBALLockBytesImpl16_SetSize
(
ILockBytes16
*
iface
,
ULARGE_INTEGER
libNewSize
)
/* [in] */
{
HGLOBALLockBytesImpl16
*
const
This
=
(
HGLOBALLockBytesImpl16
*
)
iface
;
TRACE
(
"(%p,%ld)
\n
"
,
This
,
libNewSize
.
s
.
LowPart
);
/*
* As documented.
*/
if
(
libNewSize
.
s
.
HighPart
!=
0
)
return
STG_E_INVALIDFUNCTION
;
if
(
This
->
byteArraySize
.
s
.
LowPart
==
libNewSize
.
s
.
LowPart
)
return
S_OK
;
/*
* Re allocate the HGlobal to fit the new size of the stream.
*/
This
->
supportHandle
=
GlobalReAlloc16
(
This
->
supportHandle
,
libNewSize
.
s
.
LowPart
,
0
);
if
(
This
->
supportHandle
==
0
)
return
STG_E_MEDIUMFULL
;
This
->
byteArraySize
.
s
.
LowPart
=
libNewSize
.
s
.
LowPart
;
return
S_OK
;
}
/******************************************************************************
* This method is part of the ILockBytes interface.
*
* The global memory implementation of ILockBytes does not support locking.
*
* See the documentation of ILockBytes for more info.
*/
HRESULT
WINAPI
HGLOBALLockBytesImpl16_LockRegion
(
ILockBytes16
*
iface
,
ULARGE_INTEGER
libOffset
,
/* [in] */
ULARGE_INTEGER
cb
,
/* [in] */
DWORD
dwLockType
)
/* [in] */
{
return
STG_E_INVALIDFUNCTION
;
}
/******************************************************************************
* This method is part of the ILockBytes interface.
*
* The global memory implementation of ILockBytes does not support locking.
*
* See the documentation of ILockBytes for more info.
*/
HRESULT
WINAPI
HGLOBALLockBytesImpl16_UnlockRegion
(
ILockBytes16
*
iface
,
ULARGE_INTEGER
libOffset
,
/* [in] */
ULARGE_INTEGER
cb
,
/* [in] */
DWORD
dwLockType
)
/* [in] */
{
return
STG_E_INVALIDFUNCTION
;
}
/******************************************************************************
* This method is part of the ILockBytes interface.
*
* This method returns information about the current
* byte array object.
*
* See the documentation of ILockBytes for more info.
*/
HRESULT
WINAPI
HGLOBALLockBytesImpl16_Stat
(
ILockBytes16
*
iface
,
STATSTG16
*
pstatstg
,
/* [out] */
DWORD
grfStatFlag
)
/* [in] */
{
HGLOBALLockBytesImpl16
*
const
This
=
(
HGLOBALLockBytesImpl16
*
)
iface
;
memset
(
pstatstg
,
0
,
sizeof
(
STATSTG16
));
pstatstg
->
pwcsName
=
NULL
;
pstatstg
->
type
=
STGTY_LOCKBYTES
;
pstatstg
->
cbSize
=
This
->
byteArraySize
;
return
S_OK
;
}
/******************************************************************************
* CreateILockBytesOnHGlobal [OLE2.54]
*
* Creates an ILockBytes interface for a HGLOBAL handle.
*
* Params:
* hGlobal the global handle (16bit)
* fDeleteOnRelease delete handle on release.
* ppLkbyt pointer to ILockBytes interface.
*
* Returns:
* Staddard OLE error return codes.
*
*/
HRESULT
WINAPI
CreateILockBytesOnHGlobal16
(
HGLOBAL16
hGlobal
,
BOOL16
fDeleteOnRelease
,
/*SEGPTR**/
LPLOCKBYTES16
*
ppLkbyt
)
{
HGLOBALLockBytesImpl16
*
newLockBytes
;
/* SEGPTR */
newLockBytes
=
HGLOBALLockBytesImpl16_Construct
(
hGlobal
,
fDeleteOnRelease
);
if
(
newLockBytes
!=
NULL
)
return
HGLOBALLockBytesImpl16_QueryInterface
((
ILockBytes16
*
)
newLockBytes
,
&
IID_ILockBytes
,
(
void
**
)
ppLkbyt
);
return
E_OUTOFMEMORY
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment