1/*************************************************************************/
2/* module:          SyncML WorkSpace Manager                             */
3/* file:            WSM_SM.c                                             */
4/* target system:   MS Windows                                           */
5/* target OS:       Windows 98 / NT                                      */
6/*************************************************************************/
7
8/*
9 * Copyright Notice
10 * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication
11 * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc.,
12 * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001).
13 * All Rights Reserved.
14 * Implementation of all or part of any Specification may require
15 * licenses under third party intellectual property rights,
16 * including without limitation, patent rights (such a third party
17 * may or may not be a Supporter). The Sponsors of the Specification
18 * are not responsible and shall not be held responsible in any
19 * manner for identifying or failing to identify any or all such
20 * third party intellectual property rights.
21 *
22 * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED
23 * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM,
24 * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA,
25 * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML
26 * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
27 * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
28 * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
29 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
30 * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO.,
31 * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY
32 * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF
33 * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF
34 * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL,
35 * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH
36 * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED
37 * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE.
38 *
39 * The above notice and this paragraph must be included on all copies
40 * of this document that are made.
41 *
42 */
43
44
45/**
46 * Storage Management for Workspace Manager API. <BR>
47 * MS Windows version.
48 *
49 * @version  @label
50 *
51 */
52
53#ifndef NOWSM
54// if no WSM, we can leave this one out completely
55
56
57/*************************************************************************/
58/*  Definitions                                                          */
59/*************************************************************************/
60
61#include "wsm_sm.h"
62
63#include <stdlib.h>
64#include <string.h>
65#include "libmem.h"
66#include "liblock.h" // for THREADDEBUGPRINTF %%% luz
67#include "smldef.h"
68#include "smlerr.h"
69
70
71/* Global Vars */
72/* =========== */
73
74/** root of buffer list */
75
76#include "mgr.h"
77#define root (mgrGetSyncMLAnchor())->wsmGlobals->wsmSm
78
79/* private functions prototypes */
80static Byte_t newListEle(const char *name, smWinList_t **newEle, MemHandle_t *newHandle);
81static Byte_t locateEle(const char *eleName, smWinList_t **p);
82static Byte_t locateH(MemHandle_t memH, smWinList_t **p);
83static void removeEle(const char *eleName);
84
85
86/*************************************************************************/
87/*  Internal Functions                                                   */
88/*************************************************************************/
89
90/** create new buffer element and assign name to it
91 * return pointer to new element and handle of new element
92 */
93/*
94 SCTSTK - 16/03/2002 S.H. 2002-04-05 : fixed so that it works even if the sequence of buffer termination
95 is not in the reverse order of buffer creation
96 */
97
98// luz %%% NOTE: called only from routines which lock the toolkit already,
99//               no separate lock required here
100static Byte_t newListEle(const char *name,
101  smWinList_t **newEle,
102  MemHandle_t *newHandle
103)
104{
105  smWinList_t *p;
106  int i;
107  for ( i=0; *newHandle < MAX_WSM_BUFFERS && (mgrGetSyncMLAnchor())->wsmGlobals->wsmBuf[i].memH != -1; ++i ) {};
108  if (i == MAX_WSM_BUFFERS) return 0;
109  *newHandle=i+1;
110
111  if ( ((*newEle) = smlLibMalloc(sizeof(smWinList_t))) == 0 )
112    return 0;  // no more memory
113  if ( ((*newEle)->memName = smlLibMalloc(strlen(name)+1)) == 0 ){
114    smlLibFree(*newEle);
115    return 0;  // no more memory
116    }
117  memcpy((*newEle)->memName, name, strlen(name));
118  (*newEle)->memName[strlen(name)] = '\0';
119  if ( root == 0 )
120    root = *newEle;
121  else {
122  	p=root;
123	  while ( p->next != NULL) p = p->next;
124    p->next = *newEle;
125  }
126  return 1;
127}
128
129
130/**
131 * search for buffer with name eleName and return pointer to it in p.
132 * return == 0 if not found; 1 if found
133 */
134// luz %%% NOTE: called only from routines which lock the toolkit already,
135//               no separate lock required here
136static Byte_t locateEle(const char *eleName, smWinList_t **p) {
137  *p = root;
138  while ( (*p != NULL) && (strcmp((*p)->memName, eleName) != 0) )  {
139    *p = (*p)->next;
140  }
141  if ( *p == NULL )
142    return 0;
143  else
144    return 1;
145}
146
147/**
148 * search for buffer with memHandle memH and return pointer to it in p.
149 * return == 0 if not found; 1 if found
150 */
151// luz %%% NOTE: called only from routines which lock the toolkit already,
152//               no separate lock required here
153static Byte_t locateH(MemHandle_t memH, smWinList_t **p) {
154  *p = root;
155  while ( (*p != NULL) && ((*p)->memH != memH) )  {
156    *p = (*p)->next;
157  }
158  if ( *p == NULL )
159    return 0;
160  else
161    return 1;
162}
163
164/**
165 * remove buffer with name eleName from smWinList.
166 */
167// luz %%% NOTE: called only from routines which lock the toolkit already,
168//               no separate lock required here
169static void removeEle(const char *eleName) {
170  smWinList_t *act, *old;
171
172  old = act = root;
173  while ( (act != NULL) && (strcmp(act->memName, eleName) != 0) )  {
174    old = act;
175    act = act->next;
176  }
177  if ( act != NULL ) {
178    if ( old == act )   // delete first list ele
179      root = act->next;
180    else
181      old->next = act->next;
182    smlLibFree(act->memName);
183  	smlLibFree(act);
184  }
185}
186
187
188
189
190/*************************************************************************/
191/*  External Functions                                                   */
192/*************************************************************************/
193
194
195/**
196 * FUNCTION: smCreate
197 *
198 * Creates a new memory block with name memName and size memSize.
199 *
200 * PRE-Condition:   OS does not know memName; memSize > 0
201 *
202 * POST-Condition:  memName exists with size memSize;
203 *                  memH refers to new memory block.
204 *
205 * IN:      memName
206 *          Name of new memory block
207 * IN:      memSize
208 *          Size of new memory block
209 *
210 * OUT:     memH
211 *          Handle to new memory block
212 *
213 * RETURN:  SML_ERR_OK, if O.K.
214 *          SML_ERR_WRONG_USAGE, if memName is already known to the OS
215 *          SML_ERR_INVALID_SIZE, if memSize <= 0
216 *          SML_ERR_NOT_ENOUGH_SPACE, if available memory < memSize
217 *
218 * @see  smDestroy
219 */
220Ret_t smCreate (String_t memName, MemSize_t memSize, MemHandle_t *memH) {
221  smWinList_t *pEle;     // pointer to new buffer
222
223  if ( memSize <= 0 ) {
224    return SML_ERR_INVALID_SIZE;
225  }
226  if ( locateEle(memName, &pEle) ) {
227    return SML_ERR_WRONG_USAGE;
228  }
229
230  // create new element in buffer list
231  if ( ! newListEle(memName, &pEle, memH) ) {
232    return SML_ERR_NOT_ENOUGH_SPACE;
233  }
234
235  // create memory
236  if ( (pEle->winH=smlLibMalloc(memSize)) == 0 ) {
237    smlLibFree(pEle->memName);
238 	  smlLibFree(pEle);
239    return SML_ERR_NOT_ENOUGH_SPACE;
240  }
241
242  // set new values
243  pEle->locked = 0;
244  pEle->memH = *memH;
245  pEle->memSize = memSize;
246  pEle->next = NULL;
247
248  return SML_ERR_OK;
249}
250
251
252/**
253 * FUNCTION: smOpen
254 *
255 * Open connection to memory block with name memName.
256 *
257 * PRE-Condition:   OS does know memName
258 *
259 * POST-Condition:  memH refers to memory block memName
260 *
261 * IN:      memName
262 *          Name of memory block to open<BR>
263 *          Windows version: Name is ignored
264 *
265 * OUT:     memH
266 *          Handle to opened memory block
267 *
268 * RETURN:  SML_ERR_OK, if O.K.
269 *          SML_ERR_WRONG_PARAM, if memName is unknown
270 *
271 * @see  smClose
272 */
273Ret_t smOpen (String_t memName, MemHandle_t *memH) {
274  smWinList_t *pEle;     // pointer to buffer element
275
276  if ( ! locateEle(memName, &pEle) ) {
277    return SML_ERR_WRONG_PARAM;
278  }
279
280  *memH = pEle->memH;
281  return SML_ERR_OK;
282}
283
284
285/**
286 * FUNCTION: smClose
287 *
288 * Close link to memory block.
289 *
290 * PRE-Condition:   memH is a valid memory block handle; memH is unlocked;
291 *                  no pointers to records are in use
292 *
293 * POST-Condition:  memH is not valid anymore
294 *
295 * IN:      memH
296 *          Handle to close
297 *
298 * RETURN:  SML_ERR_OK, if O.K.
299 *          SML_ERR_WRONG_USAGE, if memH is locked or unknown
300 *
301 * @see  smOpen
302 */
303Ret_t smClose (MemHandle_t memH) {
304  smWinList_t *pEle;     // pointer to buffer element
305
306  if ( ! locateH(memH, &pEle) ) {
307    return SML_ERR_WRONG_USAGE;
308  }
309
310  // reset handle
311  smlLibFree(pEle->winH);
312  pEle->memH = 0;
313  pEle->locked = 0;
314  pEle->memSize = 0;
315
316  return SML_ERR_OK;
317}
318
319
320/**
321 * FUNCTION: smDestroy
322 *
323 * Remove memory block memName within OS.
324 *
325 * PRE-Condition:   memName is a valid memory block name;
326 *                  memory block is not in use (i.e. no handles and
327 *                  pointers to this memory block are in use)
328 *
329 * POST-Condition:  memName is not a valid memory block name anymore
330 *
331 * IN:      memName
332 *          Name of memory block to remove
333 *
334 * RETURN:  SML_ERR_OK, if O.K.
335 *          SML_ERR_WRONG_PARAM, if memName is unknown
336 *          SML_ERR_WRONG_USAGE, if memory block is still locked
337 *
338 * @see  smCreate
339 */
340Ret_t smDestroy (String_t memName) {
341  smWinList_t *pEle;     // pointer to buffer element
342
343  if ( ! locateEle(memName, &pEle) ) {
344    return SML_ERR_WRONG_PARAM;
345  }
346  if ( pEle->locked ) {
347    return SML_ERR_WRONG_USAGE;
348  }
349
350  // remove memory buffer
351  removeEle(memName);
352
353  return SML_ERR_OK;
354}
355
356
357/**
358 * FUNCTION: smLock
359 *
360 * Map memory block memH to local address space.
361 *
362 * PRE-Condition:   memH is a valid handle; memory block is not locked
363 *
364 * POST-Condition:  pMem points to memory block memH;
365 *                  memory block is locked
366 *
367 * IN:      memH
368 *          Handle to memory block
369 *
370 * OUT:     pMem
371 *          Pointer to memory block memH mapped in local address space
372 *
373 * RETURN:  SML_ERR_OK, if O.K.
374 *          SML_ERR_WRONG_PARAM, if memH is unknown
375 *          SML_ERR_WRONG_USAGE, if memH was already locked
376 *          SML_ERR_UNSPECIFIC, if lock failed
377 *
378 * @see  smUnlock
379 */
380Ret_t smLock (MemHandle_t memH, MemPtr_t *pMem) {
381  smWinList_t *pEle;     // pointer to buffer element
382
383  if ( ! locateH(memH, &pEle) ) {
384    return SML_ERR_WRONG_PARAM;
385  }
386  if ( pEle->locked ) {
387    return SML_ERR_WRONG_USAGE;
388  }
389
390  *pMem = (MemPtr_t)pEle->winH;
391  pEle->locked = 1;
392
393  return SML_ERR_OK;
394}
395
396
397/**
398 * FUNCTION: smUnlock
399 *
400 * Free pointer mapped to memH memory block.
401 *
402 * PRE-Condition:   memH is a valid handle; memory block is locked
403 *
404 * POST-Condition:  memory block is unlocked
405 *
406 * IN:      memH
407 *          Handle to memory block
408 *
409 * RETURN:  SML_ERR_OK, if O.K.
410 *          SML_ERR_WRONG_PARAM, if memH is unknown
411 *          SML_ERR_WRONG_USAGE, if memH was already unlocked
412 *          SML_ERR_UNSPECIFIC, if unlock failed
413 *
414 * @see  smLock
415 */
416Ret_t smUnlock (MemHandle_t memH) {
417  smWinList_t *pEle;     // pointer to buffer element
418
419  if ( ! locateH(memH, &pEle) ) {
420    return SML_ERR_WRONG_PARAM;
421  }
422  if ( ! pEle->locked ) {
423    return SML_ERR_WRONG_USAGE;
424  }
425
426  pEle->locked = 0;
427
428  return SML_ERR_OK;
429}
430
431
432/**
433 * FUNCTION: smSetSize
434 *
435 * Set size of memory block memH to newSize.
436 *
437 * PRE-Condition:   memH is a valid handle; newSize > 0;
438 *                  memory block is unlocked
439 *
440 * POST-Condition:  memory block size = newSize
441 *
442 * IN:      memH
443 *          Handle to memory block
444 * IN:      newSize
445 *          New size of memory block
446 *
447 * RETURN:  SML_ERR_OK, if O.K.
448 *          SML_ERR_WRONG_PARAM, if memH is unknown
449 *          SML_ERR_WRONG_USAGE, if memH is locked
450 *          SML_ERR_INVALID_SIZE, if newSize <= 0
451 *          SML_ERR_NOT_ENOUGH_SPACE, if available memory < newSize
452 *
453 * @see  smGetSize
454 */
455Ret_t smSetSize (MemHandle_t memH, MemSize_t newSize) {
456  smWinList_t *pEle;     // pointer to buffer element
457
458  if ( ! locateH(memH, &pEle) ) {
459    return SML_ERR_WRONG_PARAM;
460  }
461  if ( pEle->locked ) {
462    return SML_ERR_WRONG_USAGE;
463  }
464  if ( newSize <= 0 ) {
465    return SML_ERR_INVALID_SIZE;
466  }
467
468  smlLibFree(pEle->winH);
469  if ( (pEle->winH=smlLibMalloc(newSize)) == 0 ) {
470    return SML_ERR_NOT_ENOUGH_SPACE;
471  }
472  pEle->memSize = newSize;
473
474  return SML_ERR_OK;
475}
476
477
478/**
479 * FUNCTION: smGetSize
480 *
481 * Get size of memory block memH.
482 *
483 * PRE-Condition:   memH is a valid handle
484 *
485 * POST-Condition:  actSize = memory block size
486 *
487 * IN:      memH
488 *          Handle to memory block
489 *
490 * OUT:     actSize
491 *          Actual size of memory block
492 *
493 * RETURN:  SML_ERR_OK, if O.K.
494 *          SML_ERR_WRONG_PARAM, if memH is unknown
495 *
496 * @see  smSetSize
497 */
498Ret_t smGetSize (MemHandle_t memH, MemSize_t *actSize) {
499  smWinList_t *pEle;     // pointer to buffer element
500
501  if ( ! locateH(memH, &pEle) ) {
502    return SML_ERR_WRONG_PARAM;
503  }
504
505  *actSize = pEle->memSize;
506
507  return SML_ERR_OK;
508}
509
510#endif // #ifndef NOWSM
511