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