ReactOS  0.4.15-dev-1207-g698a8e6
clist.c File Reference
#include <stdarg.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "objbase.h"
#include "shlobj.h"
#include "wine/debug.h"
Include dependency graph for clist.c:

Go to the source code of this file.

Macros

#define COBJMACROS
 
#define CLIST_ID_CONTAINER   (~0U)
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (shell)
 
static LPDATABLOCK_HEADER NextItem (LPDBLIST lpList)
 
BOOL WINAPI SHAddDataBlock (LPDBLIST *lppList, const DATABLOCK_HEADER *lpNewItem)
 
HRESULT WINAPI SHWriteDataBlockList (IStream *lpStream, LPDBLIST lpList)
 
HRESULT WINAPI SHReadDataBlockList (IStream *lpStream, LPDBLIST *lppList)
 
VOID WINAPI SHFreeDataBlockList (LPDBLIST lpList)
 
BOOL WINAPI SHRemoveDataBlock (LPDBLIST *lppList, DWORD dwSignature)
 
DATABLOCK_HEADER *WINAPI SHFindDataBlock (LPDBLIST lpList, DWORD dwSignature)
 

Macro Definition Documentation

◆ CLIST_ID_CONTAINER

#define CLIST_ID_CONTAINER   (~0U)

Definition at line 35 of file clist.c.

◆ COBJMACROS

#define COBJMACROS

Definition at line 23 of file clist.c.

Function Documentation

◆ NextItem()

static LPDATABLOCK_HEADER NextItem ( LPDBLIST  lpList)
inlinestatic

Definition at line 42 of file clist.c.

43 {
44  char* address = (char*)lpList;
45  address += lpList->cbSize;
47 }
GLuint address
Definition: glext.h:9393

Referenced by ClearCheckItems(), FreePrincipalsList(), InternalGetNextAttributeListItem(), SHAddDataBlock(), SHFindDataBlock(), SHRemoveDataBlock(), and SHWriteDataBlockList().

◆ SHAddDataBlock()

BOOL WINAPI SHAddDataBlock ( LPDBLIST lppList,
const DATABLOCK_HEADER lpNewItem 
)

Definition at line 68 of file clist.c.

69 {
70  LPDATABLOCK_HEADER lpInsertAt = NULL;
71  ULONG ulSize;
72 
73  TRACE("(%p,%p)\n", lppList, lpNewItem);
74 
75  if(!lppList || !lpNewItem)
76  return FALSE;
77 
78  if (lpNewItem->cbSize < sizeof(DATABLOCK_HEADER) ||
79  lpNewItem->dwSignature == CLIST_ID_CONTAINER)
80  return FALSE;
81 
82  ulSize = lpNewItem->cbSize;
83 
84  if(ulSize & 0x3)
85  {
86  /* Tune size to a ULONG boundary, add space for container element */
87  ulSize = ((ulSize + 0x3) & 0xFFFFFFFC) + sizeof(DATABLOCK_HEADER);
88  TRACE("Creating container item, new size = %d\n", ulSize);
89  }
90 
91  if(!*lppList)
92  {
93  /* An empty list. Allocate space for terminal ulSize also */
94  *lppList = LocalAlloc(LMEM_ZEROINIT, ulSize + sizeof(ULONG));
95  lpInsertAt = *lppList;
96  }
97  else
98  {
99  /* Append to the end of the list */
100  ULONG ulTotalSize = 0;
101  LPDATABLOCK_HEADER lpIter = *lppList;
102 
103  /* Iterate to the end of the list, calculating the total size */
104  while (lpIter->cbSize)
105  {
106  ulTotalSize += lpIter->cbSize;
107  lpIter = NextItem(lpIter);
108  }
109 
110  /* Increase the size of the list */
111  lpIter = LocalReAlloc(*lppList, ulTotalSize + ulSize+sizeof(ULONG),
113  if(lpIter)
114  {
115  *lppList = lpIter;
116  lpInsertAt = (LPDATABLOCK_HEADER)((char*)lpIter + ulTotalSize); /* At end */
117  }
118  }
119 
120  if(lpInsertAt)
121  {
122  /* Copy in the new item */
123  LPDATABLOCK_HEADER lpDest = lpInsertAt;
124 
125  if(ulSize != lpNewItem->cbSize)
126  {
127  lpInsertAt->cbSize = ulSize;
128  lpInsertAt->dwSignature = CLIST_ID_CONTAINER;
129  lpDest++;
130  }
131  memcpy(lpDest, lpNewItem, lpNewItem->cbSize);
132 
133  /* Terminate the list */
134  lpInsertAt = NextItem(lpInsertAt);
135  lpInsertAt->cbSize = 0;
136 
137  return TRUE;
138  }
139  return FALSE;
140 }
#define CLIST_ID_CONTAINER
Definition: clist.c:35
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
struct tagDATABLOCKHEADER * LPDATABLOCK_HEADER
smooth NULL
Definition: ftsmooth.c:416
#define TRACE(s)
Definition: solgame.cpp:4
#define LMEM_ZEROINIT
Definition: winbase.h:356
#define LMEM_MOVEABLE
Definition: winbase.h:350
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
struct tagDATABLOCKHEADER DATABLOCK_HEADER
HLOCAL NTAPI LocalReAlloc(HLOCAL hMem, SIZE_T dwBytes, UINT uFlags)
Definition: heapmem.c:1608
unsigned int ULONG
Definition: retypes.h:1
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1373
static LPDATABLOCK_HEADER NextItem(LPDBLIST lpList)
Definition: clist.c:42

Referenced by CShellLink::AddDataBlock(), and SHReadDataBlockList().

◆ SHFindDataBlock()

DATABLOCK_HEADER* WINAPI SHFindDataBlock ( LPDBLIST  lpList,
DWORD  dwSignature 
)

Definition at line 424 of file clist.c.

425 {
426  TRACE("(%p,%d)\n", lpList, dwSignature);
427 
428  if(lpList)
429  {
430  while(lpList->cbSize)
431  {
432  if(lpList->dwSignature == dwSignature)
433  return lpList; /* Matched */
434  else if(lpList->dwSignature == CLIST_ID_CONTAINER && lpList[1].dwSignature == dwSignature)
435  return lpList + 1; /* Contained item matches */
436 
437  lpList = NextItem(lpList);
438  }
439  }
440  return NULL;
441 }
#define CLIST_ID_CONTAINER
Definition: clist.c:35
smooth NULL
Definition: ftsmooth.c:416
#define TRACE(s)
Definition: solgame.cpp:4
static LPDATABLOCK_HEADER NextItem(LPDBLIST lpList)
Definition: clist.c:42

Referenced by CShellLink::CopyDataBlock(), CShellLink::GetAdvertiseInfo(), CShellLink::GetIconLocation(), CShellLink::GetPath(), CShellLink::SetIconLocation(), CShellLink::SetPath(), and CShellLink::WriteAdvertiseInfo().

◆ SHFreeDataBlockList()

VOID WINAPI SHFreeDataBlockList ( LPDBLIST  lpList)

Definition at line 331 of file clist.c.

332 {
333  TRACE("(%p)\n", lpList);
334 
335  if (lpList)
336  LocalFree(lpList);
337 }
#define TRACE(s)
Definition: solgame.cpp:4
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577

Referenced by CShellLink::Reset(), and CShellLink::~CShellLink().

◆ SHReadDataBlockList()

HRESULT WINAPI SHReadDataBlockList ( IStream lpStream,
LPDBLIST lppList 
)

Definition at line 235 of file clist.c.

236 {
237  DATABLOCK_HEADER bBuff[128]; /* Temporary storage for new list item */
238  ULONG ulBuffSize = sizeof(bBuff);
239  LPDATABLOCK_HEADER pItem = bBuff;
240  ULONG ulRead, ulSize;
241  HRESULT hRet = S_OK;
242 
243  TRACE("(%p,%p)\n", lpStream, lppList);
244 
245  if(*lppList)
246  {
247  /* Free any existing list */
248  LocalFree(*lppList);
249  *lppList = NULL;
250  }
251 
252  do
253  {
254  /* Read the size of the next item */
255  hRet = IStream_Read(lpStream, &ulSize,sizeof(ulSize),&ulRead);
256 
257  if(FAILED(hRet) || ulRead != sizeof(ulSize) || !ulSize)
258  break; /* Read failed or read zero size (the end of the list) */
259 
260  if(ulSize > 0xFFFF)
261  {
262  LARGE_INTEGER liZero;
263  ULARGE_INTEGER ulPos;
264 
265  liZero.QuadPart = 0;
266 
267  /* Back the stream up; this object is too big for the list */
268  if(SUCCEEDED(IStream_Seek(lpStream, liZero, STREAM_SEEK_CUR, &ulPos)))
269  {
270  liZero.QuadPart = ulPos.QuadPart - sizeof(ULONG);
271  IStream_Seek(lpStream, liZero, STREAM_SEEK_SET, NULL);
272  }
273  break;
274  }
275  else if (ulSize >= sizeof(DATABLOCK_HEADER))
276  {
277  /* Add this new item to the list */
278  if(ulSize > ulBuffSize)
279  {
280  /* We need more buffer space, allocate it */
281  LPDATABLOCK_HEADER lpTemp;
282 
283  if (pItem == bBuff)
284  lpTemp = LocalAlloc(LMEM_ZEROINIT, ulSize);
285  else
286  lpTemp = LocalReAlloc(pItem, ulSize, LMEM_ZEROINIT|LMEM_MOVEABLE);
287 
288  if(!lpTemp)
289  {
290  hRet = E_OUTOFMEMORY;
291  break;
292  }
293  ulBuffSize = ulSize;
294  pItem = lpTemp;
295  }
296 
297  pItem->cbSize = ulSize;
298  ulSize -= sizeof(pItem->cbSize); /* already read this member */
299 
300  /* Read the item Id and data */
301  hRet = IStream_Read(lpStream, &pItem->dwSignature, ulSize, &ulRead);
302 
303  if(FAILED(hRet) || ulRead != ulSize)
304  break;
305 
306  SHAddDataBlock(lppList, pItem); /* Insert Item */
307  }
308  } while(1);
309 
310  /* If we allocated space, free it */
311  if(pItem != bBuff)
312  LocalFree(pItem);
313 
314  return hRet;
315 }
static ULONG
Definition: clist.c:222
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
BOOL WINAPI SHAddDataBlock(LPDBLIST *lppList, const DATABLOCK_HEADER *lpNewItem)
Definition: clist.c:68
smooth NULL
Definition: ftsmooth.c:416
#define TRACE(s)
Definition: solgame.cpp:4
#define LMEM_ZEROINIT
Definition: winbase.h:356
LONG HRESULT
Definition: typedefs.h:79
#define LMEM_MOVEABLE
Definition: winbase.h:350
#define S_OK
Definition: intsafe.h:51
HLOCAL NTAPI LocalReAlloc(HLOCAL hMem, SIZE_T dwBytes, UINT uFlags)
Definition: heapmem.c:1608
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
unsigned int ULONG
Definition: retypes.h:1
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1373
#define SUCCEEDED(hr)
Definition: intsafe.h:49
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by CShellLink::Load().

◆ SHRemoveDataBlock()

BOOL WINAPI SHRemoveDataBlock ( LPDBLIST lppList,
DWORD  dwSignature 
)

Definition at line 355 of file clist.c.

356 {
357  LPDATABLOCK_HEADER lpList = NULL;
358  LPDATABLOCK_HEADER lpItem = NULL;
359  LPDATABLOCK_HEADER lpNext;
360  ULONG ulNewSize;
361 
362  TRACE("(%p,%d)\n", lppList, dwSignature);
363 
364  if(lppList && (lpList = *lppList))
365  {
366  /* Search for item in list */
367  while (lpList->cbSize)
368  {
369  if(lpList->dwSignature == dwSignature ||
370  (lpList->dwSignature == CLIST_ID_CONTAINER && lpList[1].dwSignature == dwSignature))
371  {
372  lpItem = lpList; /* Found */
373  break;
374  }
375  lpList = NextItem(lpList);
376  }
377  }
378 
379  if(!lpItem)
380  return FALSE;
381 
382  lpList = lpNext = NextItem(lpItem);
383 
384  /* Locate the end of the list */
385  while (lpList->cbSize)
386  lpList = NextItem(lpList);
387 
388  /* Resize the list */
389  ulNewSize = LocalSize(*lppList) - lpItem->cbSize;
390 
391  /* Copy following elements over lpItem */
392  memmove(lpItem, lpNext, (char *)lpList - (char *)lpNext + sizeof(ULONG));
393 
394  if(ulNewSize <= sizeof(ULONG))
395  {
396  LocalFree(*lppList);
397  *lppList = NULL; /* Removed the last element */
398  }
399  else
400  {
401  lpList = LocalReAlloc(*lppList, ulNewSize, LMEM_ZEROINIT|LMEM_MOVEABLE);
402  if(lpList)
403  *lppList = lpList;
404  }
405  return TRUE;
406 }
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define CLIST_ID_CONTAINER
Definition: clist.c:35
#define TRUE
Definition: types.h:120
SIZE_T NTAPI LocalSize(HLOCAL hMem)
Definition: heapmem.c:1777
#define FALSE
Definition: types.h:117
smooth NULL
Definition: ftsmooth.c:416
#define TRACE(s)
Definition: solgame.cpp:4
#define LMEM_ZEROINIT
Definition: winbase.h:356
#define LMEM_MOVEABLE
Definition: winbase.h:350
HLOCAL NTAPI LocalReAlloc(HLOCAL hMem, SIZE_T dwBytes, UINT uFlags)
Definition: heapmem.c:1608
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
unsigned int ULONG
Definition: retypes.h:1
static LPDATABLOCK_HEADER NextItem(LPDBLIST lpList)
Definition: clist.c:42

Referenced by CShellLink::RemoveDataBlock().

◆ SHWriteDataBlockList()

HRESULT WINAPI SHWriteDataBlockList ( IStream lpStream,
LPDBLIST  lpList 
)

Definition at line 179 of file clist.c.

180 {
181  ULONG ulSize;
182  HRESULT hRet = S_OK;
183 
184  TRACE("(%p,%p)\n", lpStream, lpList);
185 
186  if(lpList)
187  {
188  while (lpList->cbSize)
189  {
190  LPDATABLOCK_HEADER lpItem = lpList;
191 
192  if(lpList->dwSignature == CLIST_ID_CONTAINER)
193  lpItem++;
194 
195  hRet = IStream_Write(lpStream,lpItem,lpItem->cbSize,&ulSize);
196  if (FAILED(hRet))
197  return hRet;
198 
199  if(lpItem->cbSize != ulSize)
200  return STG_E_MEDIUMFULL;
201 
202  lpList = NextItem(lpList);
203  }
204  }
205 
206  if(SUCCEEDED(hRet))
207  {
208  ULONG ulDummy;
209  ulSize = 0;
210 
211  /* Write a terminating list entry with zero size */
212  hRet = IStream_Write(lpStream, &ulSize,sizeof(ulSize),&ulDummy);
213  }
214 
215  return hRet;
216 }
#define CLIST_ID_CONTAINER
Definition: clist.c:35
#define STG_E_MEDIUMFULL
Definition: winerror.h:2581
#define TRACE(s)
Definition: solgame.cpp:4
LONG HRESULT
Definition: typedefs.h:79
#define S_OK
Definition: intsafe.h:51
unsigned int ULONG
Definition: retypes.h:1
static LPDATABLOCK_HEADER NextItem(LPDBLIST lpList)
Definition: clist.c:42
#define SUCCEEDED(hr)
Definition: intsafe.h:49

Referenced by CShellLink::Save().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( shell  )