Changeset 959 for trunk/client/src/ndpsmb.c
- Timestamp:
- Aug 16, 2016, 5:35:07 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/client/src/ndpsmb.c
r957 r959 32 32 #include "util.h" 33 33 34 #define debug_printf(...) debuglocal(9, __VA_ARGS__)35 36 34 // ------------------------------------------------------------- 37 35 … … 43 41 void fsphUnixTimeToDosDate( time_t time, FDATE* fdate, FTIME *ftime) 44 42 { 45 43 struct tm* gmt = localtime( &time); 46 44 #if 0 // as localtime() already does dst we don't need to add something 47 if (gmt->tm_isdst>0) { 48 debug_printf( "daylight saving in effect %d, timezone %d\n",gmt->tm_isdst, timezone); 49 time -= 3600; 50 gmt = localtime( &time); 51 } 45 if (gmt->tm_isdst>0) 46 { 47 debuglocal(9, "daylight saving in effect %d, timezone %d\n",gmt->tm_isdst, timezone); 48 time -= 3600; 49 gmt = localtime( &time); 50 } 52 51 #endif 53 54 55 56 57 58 52 fdate->day = gmt->tm_mday; 53 fdate->month = gmt->tm_mon+1; 54 fdate->year = gmt->tm_year + 1900 - 1980; 55 ftime->twosecs = gmt->tm_sec/2; 56 ftime->minutes = gmt->tm_min; 57 ftime->hours = gmt->tm_hour; 59 58 } 60 59 61 60 void fsphDosDateToUnixTime( FDATE fdate, FTIME ftime, ULONG* time) 62 61 { 63 64 65 debug_printf("fsphDosDateToUnixTime time %02d:%02d:%02d\n", ftime.hours, ftime.minutes, ftime.twosecs*2);66 67 68 69 70 71 72 73 74 75 debug_printf("fsphDosDateToUnixTime time1 %d %s", *time, ctime( (time_t*)time));62 struct tm gmtime = { 0 }; 63 64 debuglocal(9, "fsphDosDateToUnixTime time %02d:%02d:%02d\n", ftime.hours, ftime.minutes, ftime.twosecs*2); 65 gmtime.tm_mday = fdate.day; 66 gmtime.tm_mon = fdate.month-1; 67 gmtime.tm_year = fdate.year + 1980 - 1900; 68 gmtime.tm_sec = ftime.twosecs*2; 69 gmtime.tm_min = ftime.minutes; 70 gmtime.tm_hour = ftime.hours; 71 gmtime.tm_isdst = -1; // force libc to check dst saving 72 73 *time = mktime( &gmtime); 74 debuglocal(9, "fsphDosDateToUnixTime time1 %d %s", *time, ctime( (time_t*)time)); 76 75 #if 0 // as mktime() already does dst we don't need to add something 77 struct tm* gmt; 78 gmt = localtime( (time_t*) time); 79 if (gmt->tm_isdst>0) { 80 debug_printf( "fsphDosDateToUnixTime daylight saving in effect %d, timezone %d\n",gmt->tm_isdst, timezone); 81 *time += 3600; 82 } 83 debug_printf( "fsphDosDateToUnixTime time2 %d %s", *time, ctime( (time_t*)time)); 76 struct tm* gmt; 77 gmt = localtime( (time_t*) time); 78 if (gmt->tm_isdst>0) 79 { 80 debuglocal(9, "fsphDosDateToUnixTime daylight saving in effect %d, timezone %d\n",gmt->tm_isdst, timezone); 81 *time += 3600; 82 } 83 debuglocal(9, "fsphDosDateToUnixTime time2 %d %s", *time, ctime( (time_t*)time)); 84 84 #endif 85 85 } … … 90 90 const char *NdpTypes[] = 91 91 { 92 93 92 "SMBFS", 93 NULL 94 94 } 95 95 ; … … 100 100 static const NDPROPERTYINFO smbProperties[] = 101 101 { 102 103 104 105 106 107 108 109 110 111 112 113 102 {ND_PROP_STRING, 0, "WORKGROUP", ""}, 103 {ND_PROP_STRING, 0, "SERVER", ""}, 104 {ND_PROP_STRING, 0, "SHARE", ""}, 105 {ND_PROP_STRING, 0, "USER", "guest"}, 106 {ND_PROP_STRING, 0, "PASSWORD", ""}, 107 {ND_PROP_STRING, 0, "SPASSWORD", ""}, 108 {ND_PROP_STRING, 0, "MASTER", "WORKGROUP"}, 109 {ND_PROP_ULONG, 0, "MASTERTYPE", "1"}, 110 {ND_PROP_ULONG, 0, "CTO", "10"}, 111 {ND_PROP_ULONG, 0, "CLD", "32"}, 112 {ND_PROP_ULONG, 0, "EASUPPORT", "1"}, 113 {ND_PROP_STRING, 0, NULL, NULL} 114 114 }; 115 115 … … 118 118 const NDPROPERTYINFO *NdpPropertiesInfo[] = 119 119 { 120 120 smbProperties 121 121 }; 122 122 … … 130 130 static int lockInit (void) 131 131 { 132 132 return ph->fsphCreateMutex (&mutex); 133 133 } 134 134 135 135 static void lockClose (void) 136 136 { 137 137 ph->fsphCloseMutex (mutex); 138 138 } 139 139 140 140 static int lockRequest (void) 141 141 { 142 142 return ph->fsphRequestMutex (mutex, SEM_INDEFINITE_WAIT); 143 143 } 144 144 145 145 static void lockRelease (void) 146 146 { 147 147 ph->fsphReleaseMutex (mutex); 148 148 } 149 149 150 150 #if LIBSMB_THREAD_SAFE==0 151 151 152 #define ENTER() do { 153 int rcLock = lockRequest();\154 if (rcLock != NO_ERROR)\155 return rcLock;\152 #define ENTER() do { \ 153 int rcLock = lockRequest(); \ 154 if (rcLock != NO_ERROR) \ 155 return rcLock; \ 156 156 } while (0) 157 157 158 #define LEAVE() do { 159 lockRelease();\158 #define LEAVE() do { \ 159 lockRelease(); \ 160 160 } while (0) 161 161 … … 167 167 int helperEASet (cli_state *cli, FEALIST *pFEAList, char *path) 168 168 { 169 int rc = 0; 170 171 if (!path || !pFEAList || pFEAList->cbList <= sizeof(long)) 172 { 173 return ERROR_EAS_NOT_SUPPORTED; 174 } 175 176 ENTER(); 177 178 do { 179 // got FEA there 180 FEA * pfea; 181 unsigned long done = sizeof(long); 182 pfea = pFEAList->list; 183 while (done < pFEAList->cbList) 184 { 185 rc = smbwrp_setea(cli, path, (char*)(pfea + 1), pfea->cbValue ? (char *)(pfea + 1) + pfea->cbName + 1: NULL, pfea->cbValue); 186 if (rc) 187 { 188 break; 189 } 190 pfea = (FEA *)((char *)(pfea + 1) + pfea->cbName + 1 + pfea->cbValue); 191 done += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue; 192 } 193 } while (0); 194 LEAVE(); 195 return rc; 169 int rc = 0; 170 171 if (!path || !pFEAList || pFEAList->cbList <= sizeof(long)) 172 return ERROR_EAS_NOT_SUPPORTED; 173 174 ENTER(); 175 176 do { 177 // got FEA there 178 FEA * pfea; 179 unsigned long done = sizeof(long); 180 pfea = pFEAList->list; 181 while (done < pFEAList->cbList) 182 { 183 rc = smbwrp_setea(cli, path, (char*)(pfea + 1), pfea->cbValue ? (char *)(pfea + 1) + pfea->cbName + 1: NULL, pfea->cbValue); 184 if (rc) 185 break; 186 pfea = (FEA *)((char *)(pfea + 1) + pfea->cbName + 1 + pfea->cbValue); 187 done += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue; 188 } 189 } while (0); 190 191 LEAVE(); 192 return rc; 196 193 } 197 194 198 195 int APIENTRY NdpPluginLoad (PLUGINHELPERTABLE2L *pPHT) 199 196 { 200 int rc; 201 HPIPE pipe; 202 unsigned long action; 203 ph = pPHT; 204 ifL = 0; 205 /* 206 if (ph->cb < sizeof (PLUGINHELPERTABLE2)) 207 { 208 return ERROR_INVALID_FUNCTION; 209 } 210 */ 211 if (ph->cb >= sizeof (PLUGINHELPERTABLE2L)) 212 { 213 ifL = 1; 214 } 215 lockInit(); 216 debugInit(); 217 debuglocal(9,"Working with %s bit fileio NDFS\n", ifL ? "64" : "32"); 218 return NO_ERROR; 197 ph = pPHT; 198 ifL = 0; 199 if (ph->cb >= sizeof (PLUGINHELPERTABLE2L)) 200 ifL = 1; 201 202 lockInit(); 203 debugInit(); 204 debuglocal(9,"Working with %s bit fileio NDFS\n", ifL ? "64" : "32"); 205 return NO_ERROR; 219 206 } 220 207 … … 222 209 int APIENTRY NdpPluginFree (void) 223 210 { 224 225 226 211 debugDelete(); 212 lockClose(); 213 return NO_ERROR; 227 214 } 228 215 … … 230 217 void getfindinfo(Connection * pConn, FILEFINDBUF3 * stat, smbwrp_fileinfo * finfo) 231 218 { 232 char * name = ph->fsphStrRChr(finfo->fname, '\\'); 233 if (name) 234 { 235 name++; 236 } 237 else 238 { 239 name = finfo->fname; 240 } 241 if (!*name) 242 { 243 name = pConn->pRes->srv.share_name; 244 } 245 strncpy(stat->achName, name, CCHMAXPATHCOMP - 1); 246 stat->cbFile = finfo->size; 247 stat->cbFileAlloc = stat->cbFile; 248 stat->oNextEntryOffset = 0ul; 249 stat->cchName = strlen(stat->achName); 250 stat->attrFile = (finfo->attr & 0x37); 251 252 fsphUnixTimeToDosDate(finfo->mtime, &stat->fdateLastWrite, &stat->ftimeLastWrite); 253 fsphUnixTimeToDosDate(finfo->ctime, &stat->fdateCreation, &stat->ftimeCreation); 254 fsphUnixTimeToDosDate(finfo->atime, &stat->fdateLastAccess, &stat->ftimeLastAccess); 219 char * name = ph->fsphStrRChr(finfo->fname, '\\'); 220 221 if (name) 222 name++; 223 else 224 name = finfo->fname; 225 226 if (!*name) 227 name = pConn->pRes->srv.share_name; 228 229 strncpy(stat->achName, name, CCHMAXPATHCOMP - 1); 230 stat->cbFile = finfo->size; 231 stat->cbFileAlloc = stat->cbFile; 232 stat->oNextEntryOffset = 0ul; 233 stat->cchName = strlen(stat->achName); 234 stat->attrFile = (finfo->attr & 0x37); 235 236 fsphUnixTimeToDosDate(finfo->mtime, &stat->fdateLastWrite, &stat->ftimeLastWrite); 237 fsphUnixTimeToDosDate(finfo->ctime, &stat->fdateCreation, &stat->ftimeCreation); 238 fsphUnixTimeToDosDate(finfo->atime, &stat->fdateLastAccess, &stat->ftimeLastAccess); 239 return; 255 240 } 256 241 257 242 int getfindinfoL(Connection * pConn, void * plist, smbwrp_fileinfo * finfo, ULONG ulAttribute, char * mask) 258 243 { 259 FILESTATUS3L stat = {0}; 260 char * name = ph->fsphStrRChr(finfo->fname, '\\'); 261 if (name) 262 { 263 name++; 264 } 265 else 266 { 267 name = finfo->fname; 268 } 269 if (!*name) 270 { 271 name = pConn->pRes->srv.share_name; 272 } 273 if (mask && (!ph->fsphAttrMatch(ulAttribute, finfo->attr & 0x37) || !ph->fsphWildMatch(mask, name, ND_IGNORE_CASE))) 274 { 275 return 0; 276 } 277 278 stat.cbFile = finfo->size; 279 stat.cbFileAlloc = stat.cbFile; 280 stat.attrFile = (finfo->attr & 0x37); 281 282 fsphUnixTimeToDosDate(finfo->mtime, &stat.fdateLastWrite, &stat.ftimeLastWrite); 283 fsphUnixTimeToDosDate(finfo->ctime, &stat.fdateCreation, &stat.ftimeCreation); 284 fsphUnixTimeToDosDate(finfo->atime, &stat.fdateLastAccess, &stat.ftimeLastAccess); 285 debug_printf( "fname %s\n", finfo->fname); 286 debug_printf( "mtime %d %s", finfo->mtime, ctime( (time_t*)&finfo->mtime)); 287 debug_printf( "ftimeLastAccess %02d:%02d:%02d\n", stat.ftimeLastWrite.hours, stat.ftimeLastWrite.minutes, stat.ftimeLastWrite.twosecs*2); 288 289 ph->fsphAddFile32L(plist, &stat, name, strlen(name), finfo, sizeof(*finfo), 0); 290 return 1; 244 FILESTATUS3L stat = {0}; 245 char * name = ph->fsphStrRChr(finfo->fname, '\\'); 246 if (name) 247 name++; 248 else 249 name = finfo->fname; 250 251 if (!*name) 252 name = pConn->pRes->srv.share_name; 253 254 if (mask && (!ph->fsphAttrMatch(ulAttribute, finfo->attr & 0x37) || !ph->fsphWildMatch(mask, name, ND_IGNORE_CASE))) 255 return 0; 256 257 stat.cbFile = finfo->size; 258 stat.cbFileAlloc = stat.cbFile; 259 stat.attrFile = (finfo->attr & 0x37); 260 261 fsphUnixTimeToDosDate(finfo->mtime, &stat.fdateLastWrite, &stat.ftimeLastWrite); 262 fsphUnixTimeToDosDate(finfo->ctime, &stat.fdateCreation, &stat.ftimeCreation); 263 fsphUnixTimeToDosDate(finfo->atime, &stat.fdateLastAccess, &stat.ftimeLastAccess); 264 debuglocal(9, "fname %s\n", finfo->fname); 265 debuglocal(9, "mtime %d %s", finfo->mtime, ctime( (time_t*)&finfo->mtime)); 266 debuglocal(9, "ftimeLastAccess %02d:%02d:%02d\n", stat.ftimeLastWrite.hours, stat.ftimeLastWrite.minutes, stat.ftimeLastWrite.twosecs*2); 267 268 ph->fsphAddFile32L(plist, &stat, name, strlen(name), finfo, sizeof(*finfo), 0); 269 return 1; 291 270 } 292 271 293 272 static unsigned char fromhex (char c) 294 273 { 295 if ('0' <= c && c <= '9') 296 { 297 return c - '0'; 298 } 299 300 if ('A' <= c && c <= 'F') 301 { 302 return c - 'A' + 0xA; 303 } 304 305 if ('a' <= c && c <= 'f') 306 { 307 return c - 'a' + 0xA; 308 } 309 310 return 0; 274 if ('0' <= c && c <= '9') 275 return c - '0'; 276 277 if ('A' <= c && c <= 'F') 278 return c - 'A' + 0xA; 279 280 if ('a' <= c && c <= 'f') 281 return c - 'a' + 0xA; 282 283 return 0; 311 284 } 312 285 313 286 static char tohex (unsigned char b) 314 287 { 315 b &= 0xF; 316 317 if (b <= 9) 318 { 319 return b + '0'; 320 } 321 322 return 'A' + (b - 0xA); 288 b &= 0xF; 289 290 if (b <= 9) 291 return b + '0'; 292 293 return 'A' + (b - 0xA); 323 294 } 324 295 325 296 static void decryptPassword (const char *pszCrypt, char *pszPlain) 326 297 { 327 /* A simple "decryption", character from the hex value. */ 328 const char *s = pszCrypt; 329 char *d = pszPlain; 330 331 while (*s) 332 { 333 *d++ = (char)((fromhex (*s++) << 4) + fromhex (*s++)); 334 } 335 336 *d++ = 0; 298 // A simple "decryption", character from the hex value. 299 const char *s = pszCrypt; 300 char *d = pszPlain; 301 302 while (*s) 303 { 304 *d++ = (char)((fromhex (*s++) << 4) + fromhex (*s++)); 305 } 306 307 *d++ = 0; 308 return; 337 309 } 338 310 339 311 static void encryptPassword (const char *pszPlain, char *pszCrypt) 340 312 { 341 /* A simple "encryption" encode each character as hex value. */ 342 const char *s = pszPlain; 343 char *d = pszCrypt; 344 345 while (*s) 346 { 347 *d++ = tohex ((*s) >> 4); 348 *d++ = tohex (*s); 349 s++; 350 } 351 352 *d++ = 0; 313 // A simple "encryption" encode each character as hex value. */ 314 const char *s = pszPlain; 315 char *d = pszCrypt; 316 317 while (*s) 318 { 319 *d++ = tohex ((*s) >> 4); 320 *d++ = tohex (*s); 321 s++; 322 } 323 324 *d++ = 0; 325 return; 353 326 } 354 327 … … 358 331 int initResource (Resource *pRes, NDPROPERTYHANDLE properties) 359 332 { 360 361 362 const CHAR* q = NULL;363 364 365 366 333 int rc = NO_ERROR; 334 unsigned long t; 335 const char * q = NULL; 336 int defaultPassword = 1; 337 338 pRes->rootlevel = 0; 339 pRes->easupport = 1; 367 340 #ifdef HAVE_KRB5_H 368 341 pRes->krb5support = 1; 369 342 #else 370 343 pRes->krb5support = 0; 371 344 #endif 372 pRes->pdc = NULL; 373 374 t = 0, q = NULL; 375 rc = ph->fsphQueryStringProperty (properties, "WORKGROUP", &q, &t); 376 if (!rc && t && *q) 377 { 378 strncpy(pRes->srv.workgroup, q, sizeof(pRes->srv.workgroup) - 1); 379 pRes->rootlevel = 1; 380 } 381 382 t = 0, q = NULL; 383 rc = ph->fsphQueryStringProperty (properties, "SERVER", &q, &t); 384 if (!rc && t && *q) 385 { 386 strncpy(pRes->srv.server_name, q, sizeof(pRes->srv.server_name) - 1); 387 pRes->rootlevel = 2; 388 } 389 390 t = 0, q = NULL; 391 rc = ph->fsphQueryStringProperty (properties, "SHARE", &q, &t); 392 if (!rc && t && *q) 393 { 394 strncpy(pRes->srv.share_name, q, sizeof(pRes->srv.share_name) - 1); 395 pRes->rootlevel = 3; 396 } 397 398 t = 0, q = NULL; 399 rc = ph->fsphQueryStringProperty (properties, "USER", &q, &t); 400 if (!rc && t && *q) 401 { 402 strncpy(pRes->srv.username, q, sizeof(pRes->srv.username) - 1); 403 } 404 405 t = 0, q = NULL; 406 rc = ph->fsphQueryStringProperty (properties, "PASSWORD", &q, &t); 407 if (!rc && t && *q) 408 { 409 strncpy(pRes->srv.password, q, sizeof(pRes->srv.password) - 1); 410 defaultPassword = 0; 411 } 412 413 t = 0, q = NULL; 414 rc = ph->fsphQueryStringProperty (properties, "SPASSWORD", &q, &t); 415 if ( rc == NO_ERROR && *q != '\0' && defaultPassword) 416 { 417 char p[1024]; 418 p[0] = 0; 419 420 decryptPassword (q, p); 421 422 if (*p) 423 { 424 strncpy(pRes->srv.password, p, sizeof(pRes->srv.password) - 1); 425 426 /* clear the plain password */ 427 ph->fsphSetProperty (properties, "PASSWORD", ""); 428 } 429 } 430 else 431 { 432 char c[1024]; 433 encryptPassword (pRes->srv.password, c); 434 435 ph->fsphSetProperty (properties, "SPASSWORD", c); 436 437 // clear the plain password 438 ph->fsphSetProperty (properties, "PASSWORD", ""); 439 } 440 441 t = 0, q = NULL; 442 rc = ph->fsphQueryStringProperty (properties, "MASTER", &q, &t); 443 if (!rc && t && *q) 444 { 445 strncpy(pRes->srv.master, q, sizeof(pRes->srv.master) - 1); 446 } 447 448 t = 0; 449 rc = ph->fsphQueryUlongProperty (properties, "MASTERTYPE", &t); 450 if (!rc) 451 { 452 if (t > 1) 453 { 454 rc = ERROR_INVALID_PARAMETER; 455 } 456 else 457 { 458 pRes->srv.ifmastergroup = t; 459 } 460 } 461 462 t = 0; 463 rc = ph->fsphQueryUlongProperty (properties, "EASUPPORT", &t); 464 if (!rc) 465 { 466 if (t > 1) 467 { 468 rc = ERROR_INVALID_PARAMETER; 469 } 470 else 471 { 472 pRes->easupport = t; 473 } 474 } 475 476 t = 0; 477 rc = ph->fsphQueryUlongProperty (properties, "CTO", &t); 478 if (!rc) 479 { 480 if (t > 600) 481 { 482 rc = ERROR_INVALID_PARAMETER; 483 } 484 else 485 { 486 pRes->cachetimeout = t; 487 } 488 } 489 490 t = 0; 491 rc = ph->fsphQueryUlongProperty (properties, "CLD", &t); 492 if (!rc) 493 { 494 if (t > 96) 495 { 496 rc = ERROR_INVALID_PARAMETER; 497 } 498 else 499 { 500 pRes->cachedepth = t; 501 } 502 } 503 504 /* 505 * Create a directory cache with expiration time and cache listings 506 * the above values come from the gui. default: timeout 10; listings: 32 507 */ 508 dircache_create(&pRes->pdc, pRes->cachetimeout, pRes->cachedepth); 509 510 return rc; 345 pRes->pdc = NULL; 346 347 t = 0, q = NULL; 348 rc = ph->fsphQueryStringProperty (properties, "WORKGROUP", &q, &t); 349 if (!rc && t && *q) 350 { 351 strncpy(pRes->srv.workgroup, q, sizeof(pRes->srv.workgroup) - 1); 352 pRes->rootlevel = 1; 353 } 354 355 t = 0, q = NULL; 356 rc = ph->fsphQueryStringProperty (properties, "SERVER", &q, &t); 357 if (!rc && t && *q) 358 { 359 strncpy(pRes->srv.server_name, q, sizeof(pRes->srv.server_name) - 1); 360 pRes->rootlevel = 2; 361 } 362 363 t = 0, q = NULL; 364 rc = ph->fsphQueryStringProperty (properties, "SHARE", &q, &t); 365 if (!rc && t && *q) 366 { 367 strncpy(pRes->srv.share_name, q, sizeof(pRes->srv.share_name) - 1); 368 pRes->rootlevel = 3; 369 } 370 371 t = 0, q = NULL; 372 rc = ph->fsphQueryStringProperty (properties, "USER", &q, &t); 373 if (!rc && t && *q) 374 strncpy(pRes->srv.username, q, sizeof(pRes->srv.username) - 1); 375 376 t = 0, q = NULL; 377 rc = ph->fsphQueryStringProperty (properties, "PASSWORD", &q, &t); 378 if (!rc && t && *q) 379 { 380 strncpy(pRes->srv.password, q, sizeof(pRes->srv.password) - 1); 381 defaultPassword = 0; 382 } 383 384 t = 0, q = NULL; 385 rc = ph->fsphQueryStringProperty (properties, "SPASSWORD", &q, &t); 386 if (rc == NO_ERROR && *q != '\0' && defaultPassword) 387 { 388 char p[1024]; 389 p[0] = 0; 390 391 decryptPassword (q, p); 392 if (*p) 393 { 394 strncpy(pRes->srv.password, p, sizeof(pRes->srv.password) - 1); 395 // clear the plain password 396 ph->fsphSetProperty (properties, "PASSWORD", ""); 397 } 398 } 399 else 400 { 401 char c[1024]; 402 encryptPassword (pRes->srv.password, c); 403 ph->fsphSetProperty (properties, "SPASSWORD", c); 404 // clear the plain password 405 ph->fsphSetProperty (properties, "PASSWORD", ""); 406 } 407 408 t = 0, q = NULL; 409 rc = ph->fsphQueryStringProperty (properties, "MASTER", &q, &t); 410 if (!rc && t && *q) 411 strncpy(pRes->srv.master, q, sizeof(pRes->srv.master) - 1); 412 413 t = 0; 414 rc = ph->fsphQueryUlongProperty (properties, "MASTERTYPE", &t); 415 if (!rc) 416 { 417 if (t > 1) 418 rc = ERROR_INVALID_PARAMETER; 419 else 420 pRes->srv.ifmastergroup = t; 421 } 422 423 t = 0; 424 rc = ph->fsphQueryUlongProperty (properties, "EASUPPORT", &t); 425 if (!rc) 426 { 427 if (t > 1) 428 rc = ERROR_INVALID_PARAMETER; 429 else 430 pRes->easupport = t; 431 } 432 433 t = 0; 434 rc = ph->fsphQueryUlongProperty (properties, "CTO", &t); 435 if (!rc) 436 { 437 if (t > 600) 438 rc = ERROR_INVALID_PARAMETER; 439 else 440 pRes->cachetimeout = t; 441 } 442 443 t = 0; 444 rc = ph->fsphQueryUlongProperty (properties, "CLD", &t); 445 if (!rc) 446 { 447 if (t > 96) 448 rc = ERROR_INVALID_PARAMETER; 449 else 450 pRes->cachedepth = t; 451 } 452 453 /* 454 * Create a directory cache with expiration time and cache listings 455 * the above values come from the gui. default: timeout 10; listings: 32 456 */ 457 dircache_create(&pRes->pdc, pRes->cachetimeout, pRes->cachedepth); 458 459 return rc; 511 460 } 512 461 513 462 int iftestpath(char * path) 514 463 { 515 char * p = path; 516 if (!path) 517 { 518 return 0; 519 } 520 while ((p = ph->fsphStrChr(p, 'A')) != NULL) 521 { 522 if (ph->fsphStrNCmp(p, "A.+,;=[].B", 10) == 0) 523 { 524 return 1; 525 } 526 p++; 527 } 528 return 0; 464 char * p = path; 465 if (!path) 466 return 0; 467 468 while ((p = ph->fsphStrChr(p, 'A')) != NULL) 469 { 470 if (ph->fsphStrNCmp(p, "A.+,;=[].B", 10) == 0) 471 return 1; 472 p++; 473 } 474 return 0; 529 475 } 530 476 531 477 int pathparser(Resource *pRes, Connection * pConn, char * path, char * result) 532 478 { 533 534 535 536 { 537 return ERROR_INVALID_PARAMETER; 538 } 539 // handle special case when someone wants to test support ofLFN or smth similar540 if (iftestpath(path)) 541 { 542 strcpy(result, "\\A.+,;=[].B"); 543 return NO_ERROR;544 } 545 546 rootlevel = pRes->rootlevel; 547 if (*path == '\\') path++;548 549 if (rootlevel < 3) 550 { 551 char * p; 552 // flag: 1 parameters changed, reconnection required, 0 do nothing 553 int newlevel = 0; 554 // use a temporary resource to test disconnection/reconnection 555 Resource tmpRes; 556 // copy exising data 557 memcpy( &tmpRes, pRes, sizeof( tmpRes)); 558 // pointer to new connection fields 559 smbwrp_server * tmp = &tmpRes.srv; 560 if (rootlevel == 0) 561 { 562 p = ph->fsphStrChr(path, '\\'); 563 if (!p) 564 { 565 566 } 567 if (strlen(tmp->workgroup) != p - path 568 || (p == path || ph->fsphStrNICmp(path, tmp->workgroup, p - path))) 569 { 570 strncpy(tmp->workgroup, path, p - path); 571 tmp->workgroup[p - path] = 0;572 newlevel = 1;573 } 574 path = *p == '\\' ? p + 1 : p; 575 rootlevel = 1;576 } 577 if (rootlevel == 1) // root path starts from server name 578 { 579 p = ph->fsphStrChr(path, '\\'); 580 if (!p) 581 { 582 p = path + strlen(path); 583 } 584 if (strlen(tmp->server_name) != p - path 585 || (p == path || ph->fsphStrNICmp(path, tmp->server_name, p - path))) 586 { 587 strncpy(tmp->server_name, path, p - path); 588 tmp->server_name[p - path] = 0; 589 newlevel = 1;590 } 591 path = *p == '\\' ? p + 1 : p;592 rootlevel = 2; 593 } 594 if (rootlevel == 2) // root path starts from share name 595 { 596 p = ph->fsphStrChr(path, '\\'); 597 if (!p) 598 599 p = path + strlen(path);600 } 601 if (strlen(tmp->share_name) != (p - path) 602 || (p == path || ph->fsphStrNICmp(path, tmp->share_name, p - path))) 603 { 604 strncpy(tmp->share_name, path, p - path); 605 tmp->share_name[p - path] = 0; 606 newlevel = 1; 607 } 608 path = *p == '\\' ? p + 1 : p;609 } 610 if (newlevel) 611 { 612 // reconnect to server here, first test new connection 613 cli_state* tmp_cli = NULL; 614 rc = smbwrp_connect( &tmpRes, &tmp_cli); 615 if (!rc) 616 { 617 // new connection is ok, disconnect old one 618 cli_state* cli = pConn->cli;619 smbwrp_disconnect( pRes, cli); 620 // save tmp data structure 621 memcpy( pRes, &tmpRes, sizeof( tmpRes)); 622 // save new connection handle 623 pConn->cli = tmp_cli;624 } 625 } 626 } 627 628 strcpy(result, "\\"); 629 strncat(result, path, CCHMAXPATH); 630 631 return rc; 632 } 633 634 635 // ------------------------------------------------------------- 479 int rootlevel; 480 int rc = NO_ERROR; 481 if (!pRes || !path || !result) 482 return ERROR_INVALID_PARAMETER; 483 484 /* handle special case when someone wants to test support of 485 * LFN or smth similar 486 */ 487 if (iftestpath(path)) 488 { 489 strcpy(result, "\\A.+,;=[].B"); 490 return NO_ERROR; 491 } 492 493 rootlevel = pRes->rootlevel; 494 if (*path == '\\') path++; 495 496 if (rootlevel < 3) 497 { 498 char * p; 499 // flag: 1 parameters changed, reconnection required, 0 do nothing 500 int newlevel = 0; 501 // use a temporary resource to test disconnection/reconnection 502 Resource tmpRes; 503 // copy exising data 504 memcpy( &tmpRes, pRes, sizeof( tmpRes)); 505 // pointer to new connection fields 506 smbwrp_server * tmp = &tmpRes.srv; 507 if (rootlevel == 0) 508 { 509 p = ph->fsphStrChr(path, '\\'); 510 if (!p) 511 p = path + strlen(path); 512 513 if (strlen(tmp->workgroup) != p - path || 514 (p == path || 515 ph->fsphStrNICmp(path, tmp->workgroup, p - path))) 516 { 517 strncpy(tmp->workgroup, path, p - path); 518 tmp->workgroup[p - path] = 0; 519 newlevel = 1; 520 } 521 path = *p == '\\' ? p + 1 : p; 522 rootlevel = 1; 523 } 524 525 if (rootlevel == 1) // root path starts from server name 526 { 527 p = ph->fsphStrChr(path, '\\'); 528 if (!p) 529 p = path + strlen(path); 530 531 if (strlen(tmp->server_name) != p - path || 532 (p == path || 533 ph->fsphStrNICmp(path, tmp->server_name, p - path))) 534 { 535 strncpy(tmp->server_name, path, p - path); 536 tmp->server_name[p - path] = 0; 537 newlevel = 1; 538 } 539 path = *p == '\\' ? p + 1 : p; 540 rootlevel = 2; 541 } 542 543 if (rootlevel == 2) // root path starts from share name 544 { 545 p = ph->fsphStrChr(path, '\\'); 546 if (!p) 547 p = path + strlen(path); 548 549 if (strlen(tmp->share_name) != (p - path) || 550 (p == path || 551 ph->fsphStrNICmp(path, tmp->share_name, p - path))) 552 { 553 strncpy(tmp->share_name, path, p - path); 554 tmp->share_name[p - path] = 0; 555 newlevel = 1; 556 } 557 path = *p == '\\' ? p + 1 : p; 558 } 559 560 if (newlevel) 561 { 562 // reconnect to server here, first test new connection 563 cli_state* tmp_cli = NULL; 564 rc = smbwrp_connect( &tmpRes, &tmp_cli); 565 if (!rc) 566 { 567 // new connection is ok, disconnect old one 568 cli_state* cli = pConn->cli; 569 smbwrp_disconnect( pRes, cli); 570 // save tmp data structure 571 memcpy( pRes, &tmpRes, sizeof( tmpRes)); 572 // save new connection handle 573 pConn->cli = tmp_cli; 574 } 575 } 576 } 577 578 strcpy(result, "\\"); 579 strncat(result, path, CCHMAXPATH); 580 return rc; 581 } 636 582 637 583 /* check if the requested resource is available */ 638 584 static int checkMountResource( Resource* pRes) 639 585 { 640 int rc; 641 unsigned long action; 642 cli_state* cli = NULL; 643 644 debug_printf("checkMountResource in tid#%d\n", _gettid()); 645 rc = smbwrp_connect( pRes, &cli); 646 /* changed to real error codes SCS 647 if (rc) 648 rc = (rc == 7 ? ERROR_BAD_DEV_TYPE : ERROR_ACCESS_DENIED); */ 649 switch (rc) { 650 case 0: 651 rc = NO_ERROR; 652 break; 653 case 1: 654 case 10: 655 case 11: 656 rc = ERROR_BAD_NET_NAME; 657 break; 658 case 2: 659 rc = ERROR_INIT_ROUTINE_FAILED; 660 break; 661 case 3: 662 rc = ERROR_BAD_NET_RESP; 663 break; 664 case 4: 665 rc = ERROR_NETWORK_BUSY; 666 break; 667 case 6: 668 rc = ERROR_NETWORK_ACCESS_DENIED; 669 break; 670 case 7: 671 rc = ERROR_BAD_NETPATH; 672 break; 673 default: 674 rc = ERROR_UNEXP_NET_ERR; 675 break; 676 } /* endswitch */ 677 678 smbwrp_disconnect( pRes, cli); 679 680 return rc; 586 int rc; 587 unsigned long action; 588 cli_state* cli = NULL; 589 590 debuglocal(9, "checkMountResource in tid#%d\n", _gettid()); 591 rc = smbwrp_connect( pRes, &cli); 592 switch (rc) 593 { 594 case 0: 595 rc = NO_ERROR; 596 break; 597 case 1: 598 case 10: 599 case 11: 600 rc = ERROR_BAD_NET_NAME; 601 break; 602 case 2: 603 rc = ERROR_INIT_ROUTINE_FAILED; 604 break; 605 case 3: 606 rc = ERROR_BAD_NET_RESP; 607 break; 608 case 4: 609 rc = ERROR_NETWORK_BUSY; 610 break; 611 case 6: 612 rc = ERROR_NETWORK_ACCESS_DENIED; 613 break; 614 case 7: 615 rc = ERROR_BAD_NETPATH; 616 break; 617 default: 618 rc = ERROR_UNEXP_NET_ERR; 619 break; 620 } /* endswitch */ 621 622 smbwrp_disconnect( pRes, cli); 623 return rc; 681 624 } 682 625 683 626 int APIENTRY NdpMountResource (HRESOURCE *presource, int type, NDPROPERTYHANDLE properties) 684 627 { 685 int rc = NO_ERROR; 686 unsigned long objany = OBJ_ANY; 687 Resource *pRes = NULL; 688 689 ENTER(); 690 691 debuglocal(9,"NdpMountResource in\n"); 692 693 // init code 694 smbwrp_init(); 695 696 /* since samba plugin support only 1 type of resources we do not need */ 697 /* to check what the found type really is */ 698 pRes = malloc( sizeof(Resource)); 699 if (pRes == NULL) 700 { 701 rc = ERROR_NOT_ENOUGH_MEMORY; 702 } 703 else 704 { 705 memset(pRes, 0, sizeof(Resource)); 706 //pRes->objany = objany; 707 // parse init string 708 rc = initResource (pRes, properties); 709 // try to connect to resource (check type) only if thread!=1, so ndctl startup 710 // is not slowed down by network connections. 711 // ndctl does mounting on main thread (#1) 712 // nd/ndpm do not use main thread 713 if (!rc && _gettid()!=1) 714 rc = checkMountResource( pRes); 715 if (!rc) 716 { 717 // store resource data 718 *presource = (HRESOURCE)pRes; 719 } 720 else 721 { 722 free(pRes); 723 } 724 } 725 debuglocal(9,"NdpMountResource rc=%d\n", rc); 726 LEAVE(); 727 return rc; 728 } 729 730 // ------------------------------------------------------------- 628 int rc = NO_ERROR; 629 unsigned long objany = OBJ_ANY; 630 Resource *pRes = NULL; 631 632 ENTER(); 633 634 debuglocal(9,"NdpMountResource in\n"); 635 // init code 636 smbwrp_init(); 637 638 /* 639 * since samba plugin support only 1 type of resources we do not need 640 * to check what the found type really is 641 */ 642 pRes = malloc( sizeof(Resource)); 643 if (pRes == NULL) 644 rc = ERROR_NOT_ENOUGH_MEMORY; 645 else 646 { 647 memset(pRes, 0, sizeof(Resource)); 648 // parse init string 649 rc = initResource (pRes, properties); 650 /* 651 * try to connect to resource (check type) only if thread!=1, 652 * so ndctl startup is not slowed down by network connections. 653 * ndctl does mounting on main thread (#1) 654 * nd/ndpm do not use main thread 655 */ 656 if (!rc && _gettid()!=1) 657 rc = checkMountResource( pRes); 658 if (!rc) 659 { 660 // store resource data 661 *presource = (HRESOURCE)pRes; 662 } 663 else 664 free(pRes); 665 666 } 667 668 debuglocal(9, "NdpMountResource rc=%d\n", rc); 669 LEAVE(); 670 return rc; 671 } 731 672 732 673 int APIENTRY NdpFreeResource (HRESOURCE resource) 733 674 { 734 Resource *pRes = (Resource *)resource; 735 ENTER(); 736 dircache_delete(pRes->pdc); 737 memset(&pRes->srv, 0, sizeof(pRes->srv)); 738 free(pRes); 739 debuglocal(9,"NdpFreeResource %d\n", NO_ERROR); 740 LEAVE(); 741 return NO_ERROR; 742 } 743 744 // ------------------------------------------------------------- 675 Resource *pRes = (Resource *)resource; 676 ENTER(); 677 dircache_delete(pRes->pdc); 678 memset(&pRes->srv, 0, sizeof(pRes->srv)); 679 free(pRes); 680 debuglocal(9, "NdpFreeResource %d\n", NO_ERROR); 681 LEAVE(); 682 return NO_ERROR; 683 } 745 684 746 685 int APIENTRY NdpRsrcCompare (HRESOURCE resource, HRESOURCE resource2) 747 686 { 748 Resource *pRes = (Resource *)resource; 749 Resource *pRes2 = (Resource *)resource2; 750 int rc = ND_RSRC_DIFFERENT; 751 752 debuglocal(9,"NdpRsrcCompare in\n"); 753 if (ph->fsphStrICmp(pRes->srv.server_name, pRes2->srv.server_name) == 0 754 && ph->fsphStrICmp(pRes->srv.share_name, pRes2->srv.share_name) == 0 755 && ph->fsphStrICmp(pRes->srv.username, pRes2->srv.username) == 0 756 && ph->fsphStrICmp(pRes->srv.workgroup, pRes2->srv.workgroup) == 0) 757 { 758 // resources are equal 759 rc = ND_RSRC_EQUAL; 760 } 761 762 debuglocal(9,"NdpRsrcCompare %d\n", rc); 763 764 return rc; 687 Resource *pRes = (Resource *)resource; 688 Resource *pRes2 = (Resource *)resource2; 689 int rc = ND_RSRC_DIFFERENT; 690 691 debuglocal(9, "NdpRsrcCompare in\n"); 692 if (ph->fsphStrICmp(pRes->srv.server_name, pRes2->srv.server_name) == 0 693 && ph->fsphStrICmp(pRes->srv.share_name, pRes2->srv.share_name) == 0 694 && ph->fsphStrICmp(pRes->srv.username, pRes2->srv.username) == 0 695 && ph->fsphStrICmp(pRes->srv.workgroup, pRes2->srv.workgroup) == 0) 696 { 697 // resources are equal 698 rc = ND_RSRC_EQUAL; 699 } 700 701 debuglocal(9, "NdpRsrcCompare %d\n", rc); 702 return rc; 765 703 } 766 704 767 705 int APIENTRY NdpRsrcUpdate (HRESOURCE resource, HRESOURCE resource2) 768 706 { 769 770 debuglocal(9,"NdpRsrcUpdate %d\n", NO_ERROR);771 707 // do nothing 708 debuglocal(9, "NdpRsrcUpdate %d\n", NO_ERROR); 709 return NO_ERROR; 772 710 } 773 711 774 712 int APIENTRY NdpRsrcQueryInfo (HRESOURCE resource, ULONG *pulFlags, void *pdata, ULONG insize, ULONG *poutlen) 775 713 { 776 Resource *pRes = (Resource *)resource; 777 int rc = NO_ERROR; 778 char s[4096]; 779 780 debuglocal(9,"NdpRsrcQueryInfo in\n"); 781 782 switch (pRes->rootlevel) 783 { 784 case 0: 785 { 786 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s \\\\@%s", ifL ? "64" : "32", pRes->srv.username); 787 } break; 788 case 1: 789 { 790 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s %s: \\\\@%s", ifL ? "64" : "32", pRes->srv.workgroup, pRes->srv.username); 791 } break; 792 case 2: 793 { 794 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s \\\\%s%s%s@%s", ifL ? "64" : "32", *pRes->srv.workgroup ? pRes->srv.workgroup : "", *pRes->srv.workgroup ? ":" : "", pRes->srv.server_name, pRes->srv.username); 795 } break; 796 default: 797 { 798 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s \\\\%s%s%s\\%s@%s", ifL ? "64" : "32", *pRes->srv.workgroup ? pRes->srv.workgroup : "", *pRes->srv.workgroup ? ":" : "", pRes->srv.server_name, pRes->srv.share_name, pRes->srv.username); 799 } break; 800 } 801 *poutlen = strlen(s) + 1; 802 if (*poutlen > insize) 803 { 804 rc = ERROR_BUFFER_OVERFLOW; 805 } 806 else 807 { 808 memcpy(pdata, s, *poutlen); 809 } 810 811 debuglocal(9,"NdpRsrcQueryInfo %d\n", rc); 812 813 return rc; 714 Resource *pRes = (Resource *)resource; 715 int rc = NO_ERROR; 716 char s[4096]; 717 718 debuglocal(9, "NdpRsrcQueryInfo in\n"); 719 720 switch (pRes->rootlevel) 721 { 722 case 0: 723 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s \\\\@%s", ifL ? "64" : "32", pRes->srv.username); 724 break; 725 case 1: 726 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s %s: \\\\@%s", ifL ? "64" : "32", pRes->srv.workgroup, pRes->srv.username); 727 break; 728 case 2: 729 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s \\\\%s%s%s@%s", ifL ? "64" : "32", *pRes->srv.workgroup ? pRes->srv.workgroup : "", *pRes->srv.workgroup ? ":" : "", pRes->srv.server_name, pRes->srv.username); 730 break; 731 default: 732 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s \\\\%s%s%s\\%s@%s", ifL ? "64" : "32", *pRes->srv.workgroup ? pRes->srv.workgroup : "", *pRes->srv.workgroup ? ":" : "", pRes->srv.server_name, pRes->srv.share_name, pRes->srv.username); 733 break; 734 } 735 *poutlen = strlen(s) + 1; 736 if (*poutlen > insize) 737 rc = ERROR_BUFFER_OVERFLOW; 738 else 739 memcpy(pdata, s, *poutlen); 740 741 debuglocal(9, "NdpRsrcQueryInfo %d\n", rc); 742 return rc; 814 743 } 815 744 816 745 int APIENTRY NdpRsrcQueryFSAttach (HRESOURCE resource, void *pdata, ULONG insize, ULONG *poutlen) 817 746 { 818 819 /* just return the resource info string */ 820 747 ULONG ulDummy = 0; 748 // just return the resource info string 749 return NdpRsrcQueryInfo (resource, &ulDummy, pdata, insize, poutlen); 821 750 } 822 751 823 752 int APIENTRY NdpRsrcQueryFSAllocate (HRESOURCE resource, NDFSALLOCATE *pfsa) 824 753 { 825 Resource *pRes = (Resource *)resource; 826 int rc = NO_ERROR, rc1; 827 unsigned long action = 0; 828 cli_state* cli = NULL; 829 FSALLOCATE fsa; 830 831 ENTER(); 832 debuglocal(9,"NdpRsrcQueryFSAllocate %08x\n", pfsa); 833 834 if (!pfsa) 835 { 836 LEAVE(); 837 return NO_ERROR; 838 } 839 840 debug_printf("checkMountResource in tid#%d\n", _gettid()); 841 rc = smbwrp_connect( pRes, &cli); 842 if (rc) 843 { 844 debuglocal(9,"NdpCreateConnection failed rc=%d\n", rc); 845 pfsa->cSectorUnit = 1; 846 pfsa->cUnit = 123456; 847 pfsa->cUnitAvail = 123456; 848 pfsa->cbSector = 2048; 849 rc = (rc == 7 ? ERROR_BAD_DEV_TYPE : ERROR_ACCESS_DENIED); 850 LEAVE(); 851 return rc; 852 } 853 854 rc = smbwrp_dskattr( cli, &fsa); 855 if (rc) 856 { 857 pfsa->cSectorUnit = 1; 858 pfsa->cUnit = 123456; 859 pfsa->cUnitAvail = 123456; 860 pfsa->cbSector = 2048; 861 //rc = rc ? rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER); 862 } 863 else 864 { 865 pfsa->cSectorUnit = fsa.cSectorUnit; 866 pfsa->cUnit = fsa.cUnit; 867 pfsa->cUnitAvail = fsa.cUnitAvail; 868 pfsa->cbSector = fsa.cbSector; 869 } 870 871 smbwrp_disconnect( pRes, cli); 872 873 debuglocal(9,"NdpRsrcQueryFSAllocate %d/%d (cUnit = %d/cUnitAvail = %d/cbSector = %d)\n", rc, rc1, pfsa->cUnit, pfsa->cUnitAvail, pfsa->cbSector); 874 LEAVE(); 875 return rc; 876 } 877 878 // ------------------------------------------------------------- 754 Resource *pRes = (Resource *)resource; 755 int rc = NO_ERROR, rc1; 756 unsigned long action = 0; 757 cli_state* cli = NULL; 758 FSALLOCATE fsa; 759 760 ENTER(); 761 debuglocal(9, "NdpRsrcQueryFSAllocate %08x\n", pfsa); 762 763 if (!pfsa) 764 { 765 LEAVE(); 766 return NO_ERROR; 767 } 768 769 debuglocal(9, "NdpRsrcQueryFSAllocate in tid#%d\n", _gettid()); 770 rc = smbwrp_connect( pRes, &cli); 771 if (rc) 772 { 773 debuglocal(9, "NdpRsrcQueryFSAllocate smbwrp_connect failed rc=%d\n", rc); 774 pfsa->cSectorUnit = 1; 775 pfsa->cUnit = 123456; 776 pfsa->cUnitAvail = 123456; 777 pfsa->cbSector = 2048; 778 rc = (rc == 7 ? ERROR_BAD_DEV_TYPE : ERROR_ACCESS_DENIED); 779 LEAVE(); 780 return rc; 781 } 782 783 rc = smbwrp_dskattr( cli, &fsa); 784 if (rc) 785 { 786 pfsa->cSectorUnit = 1; 787 pfsa->cUnit = 123456; 788 pfsa->cUnitAvail = 123456; 789 pfsa->cbSector = 2048; 790 //rc = rc ? rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER); 791 } 792 else 793 { 794 pfsa->cSectorUnit = fsa.cSectorUnit; 795 pfsa->cUnit = fsa.cUnit; 796 pfsa->cUnitAvail = fsa.cUnitAvail; 797 pfsa->cbSector = fsa.cbSector; 798 } 799 800 smbwrp_disconnect( pRes, cli); 801 debuglocal(9, "NdpRsrcQueryFSAllocate %d/%d (cUnit = %d/cUnitAvail = %d/cbSector = %d)\n", rc, rc1, pfsa->cUnit, pfsa->cUnitAvail, pfsa->cbSector); 802 803 LEAVE(); 804 return rc; 805 } 879 806 880 807 int APIENTRY NdpCreateConnection (HRESOURCE resource, HCONNECTION *pconn) 881 808 { 882 int rc = 0; 883 Resource * pRes = (Resource *)resource; 884 unsigned long action; 885 Connection *pConn = NULL; 886 887 ENTER(); 888 889 debuglocal(9,"NdpCreateConnection in\n"); 890 891 pConn = malloc( sizeof(Connection)); 892 if (pConn == NULL) 893 { 894 rc = ERROR_NOT_ENOUGH_MEMORY; 895 } 896 if (rc) 897 { 898 debuglocal(9,"NdpCreateConnection ERROR_NOT_ENOUGH_MEMORY %d\n", rc); 899 LEAVE(); 900 return rc; 901 } 902 memset(pConn, 0, sizeof(Connection)); 903 pConn->pRes = pRes; 904 pConn->file.fd = -1; 905 906 debuglocal(9,"NdpCreateConnection send CONNECT\n"); 907 rc = smbwrp_connect( pRes, &pConn->cli); 908 if (rc) 909 { 910 free(pConn); 911 pConn = NULL; 912 rc = (rc == 7 ? ERROR_BAD_DEV_TYPE : ERROR_INVALID_PARAMETER); 913 } 914 915 *pconn = (HCONNECTION)pConn; 916 debuglocal(9,"NdpCreateConnection [%p] %d\n", pConn, rc); 917 LEAVE(); 918 return rc; 919 } 920 921 // ------------------------------------------------------------- 809 int rc = 0; 810 Resource * pRes = (Resource *)resource; 811 unsigned long action; 812 Connection *pConn = NULL; 813 814 ENTER(); 815 816 debuglocal(9, "NdpCreateConnection in\n"); 817 818 pConn = malloc( sizeof(Connection)); 819 if (pConn == NULL) 820 rc = ERROR_NOT_ENOUGH_MEMORY; 821 822 if (rc) 823 { 824 debuglocal(9, "NdpCreateConnection ERROR_NOT_ENOUGH_MEMORY %d\n", rc); 825 LEAVE(); 826 return rc; 827 } 828 829 memset(pConn, 0, sizeof(Connection)); 830 pConn->pRes = pRes; 831 pConn->file.fd = -1; 832 833 debuglocal(9, "NdpCreateConnection send CONNECT\n"); 834 rc = smbwrp_connect( pRes, &pConn->cli); 835 if (rc) 836 { 837 free(pConn); 838 pConn = NULL; 839 rc = (rc == 7 ? ERROR_BAD_DEV_TYPE : ERROR_INVALID_PARAMETER); 840 } 841 842 *pconn = (HCONNECTION)pConn; 843 debuglocal(9, "NdpCreateConnection [%p] %d\n", pConn, rc); 844 845 LEAVE(); 846 return rc; 847 } 922 848 923 849 int APIENTRY NdpFreeConnection (HCONNECTION conn) 924 850 { 925 Connection *pConn = (Connection *)conn; 926 Resource *pRes = pConn->pRes; 927 int rc; 928 929 ENTER(); 930 931 debuglocal(9,"NdpFreeConnection in [%p]\n", pConn); 932 if (pConn->file.fd >= 0) 933 { 934 rc = smbwrp_close( pConn->cli, &pConn->file); 935 pConn->file.fd = -1; 936 } 937 938 smbwrp_disconnect( pRes, pConn->cli); 939 940 free(pConn); 941 debuglocal(9,"NdpFreeConnection %d\n", NO_ERROR); 942 LEAVE(); 943 return NO_ERROR; 944 } 945 946 // ------------------------------------------------------------- 851 Connection *pConn = (Connection *)conn; 852 Resource *pRes = pConn->pRes; 853 int rc; 854 855 ENTER(); 856 857 debuglocal(9, "NdpFreeConnection in [%p]\n", pConn); 858 if (pConn->file.fd >= 0) 859 { 860 rc = smbwrp_close( pConn->cli, &pConn->file); 861 pConn->file.fd = -1; 862 } 863 864 smbwrp_disconnect( pRes, pConn->cli); 865 866 free(pConn); 867 debuglocal(9, "NdpFreeConnection %d\n", NO_ERROR); 868 869 LEAVE(); 870 return NO_ERROR; 871 } 947 872 948 873 /* … … 965 890 int APIENTRY NdpQueryPathInfo (HCONNECTION conn, void *plist, char *szPath) 966 891 { 967 968 969 970 971 972 973 974 975 976 977 debuglocal(9,"NdpQueryPathInfo in [%p] <%s>\n", pConn, szPath);892 Connection *pConn = (Connection *)conn; 893 Resource *pRes = pConn->pRes; 894 smbwrp_fileinfo finfo; 895 int rc = 0; 896 int rcCon = 0; 897 unsigned long action; 898 char path[CCHMAXPATH+1] = {0}; 899 900 ENTER(); 901 902 debuglocal(9, "NdpQueryPathInfo in [%p] <%s>\n", pConn, szPath); 978 903 979 // is wildcard is specified, we suppose parent dir exist, so exit immediately 980 if (ph->fsphStrChr(szPath, '*') || ph->fsphStrChr(szPath, '?')) 981 { 982 LEAVE(); 983 return ERROR_FILE_NOT_FOUND; 984 } 985 986 987 do { 988 /* First check if there is information in the directory cache. */ 989 unsigned long ulAge = 0; 990 if (dircache_find_path(pRes->pdc, szPath, &finfo, &ulAge)) 991 { 992 if (ulAge <= 15) /* @todo configurable. */ 993 { 994 rc = NO_ERROR; 995 finfo.easize = -1; 996 getfindinfoL(pConn, plist, &finfo, 0, NULL); 997 break; 998 } 999 } 1000 1001 rc = pathparser(pRes, pConn, szPath, path); 1002 debuglocal(9,"NdpQueryPathInfo pathparser for <%s> rc=%d\n", path, rc); 1003 switch (rc) 1004 { 1005 case NO_ERROR : 1006 case ERROR_FILE_NOT_FOUND: 1007 case ERROR_PATH_NOT_FOUND: 1008 case ERROR_ACCESS_DENIED: 1009 case ERROR_INVALID_PARAMETER: 1010 { 1011 break; 1012 } 1013 default : 1014 { 1015 rc = ERROR_PATH_NOT_FOUND; 1016 } 1017 } 1018 if (rc) 1019 { 1020 break; 1021 } 1022 strncpy(finfo.fname, path, sizeof(finfo.fname) - 1); 1023 debuglocal(9,"NdpQueryPathInfo smbwrp_getattr for <%s>\n", path); 1024 rc = smbwrp_getattr( &pRes->srv, pConn->cli, &finfo); 1025 if (rc) 1026 { 1027 // remote server not available for first time? 1028 if (rc == ERROR_REM_NOT_LIST) 1029 { 1030 // free current cli resources 1031 smbwrp_disconnect( pRes, pConn->cli); 1032 // reconnect 1033 rcCon = smbwrp_connect( pRes, &pConn->cli); 1034 if (rcCon != NO_ERROR) 1035 debuglocal(9,"NdpQueryPathInfo smbwrp_connect rc = %d\n", rcCon); 1036 1037 // try file list again if reconnecting worked 1038 if (rcCon == NO_ERROR) 1039 rc = smbwrp_getattr( &pRes->srv, pConn->cli, &finfo); 1040 } 1041 debuglocal(9,"NdpQueryPathInfo smbwrp_getattr, rc = %d\n", rc); 1042 switch (rc) 1043 { 1044 case NO_ERROR : 1045 case ERROR_FILE_NOT_FOUND: 1046 case ERROR_PATH_NOT_FOUND: 1047 case ERROR_ACCESS_DENIED: 1048 case ERROR_INVALID_PARAMETER: 1049 case ERROR_REM_NOT_LIST: 1050 break; 1051 default : 1052 { 1053 rc = ERROR_PATH_NOT_FOUND; 1054 } 1055 } 1056 } 1057 1058 if (rc == NO_ERROR) { 1059 finfo.easize = -1; 1060 getfindinfoL(pConn, plist, &finfo, 0, NULL); 1061 } 1062 else if (rc == ERROR_FILE_NOT_FOUND) 1063 { 1064 // now try the upper path 1065 char * p = ph->fsphStrRChr(finfo.fname, '\\'); 1066 if (p && p > finfo.fname) 1067 { 1068 *p = 0; 1069 rc = smbwrp_getattr( &pRes->srv, pConn->cli, &finfo); 1070 debuglocal(9,"NdpQueryPathInfo upper path in <%s>, rc = %d\n", finfo.fname, rc); 1071 if (rc == NO_ERROR) 1072 { 1073 rc = (finfo.attr & FILE_DIRECTORY) !=0 ? 1074 ERROR_FILE_NOT_FOUND:ERROR_PATH_NOT_FOUND; 1075 } 1076 else if (rc != ERROR_REM_NOT_LIST) 1077 { 1078 rc = ERROR_PATH_NOT_FOUND; 1079 } 1080 } 1081 } 1082 } while (0); 1083 debuglocal(9,"NdpQueryPathInfo <%s> (%s) %d\n", szPath, path, rc); 1084 1085 LEAVE(); 1086 return rc; 1087 } 1088 1089 // ------------------------------------------------------------- 904 /* 905 * if wildcard is specified, we suppose parent dir exist, 906 * so exit immediately 907 */ 908 if (ph->fsphStrChr(szPath, '*') || ph->fsphStrChr(szPath, '?')) 909 { 910 LEAVE(); 911 return ERROR_FILE_NOT_FOUND; 912 } 913 914 do { 915 // First check if there is information in the directory cache. 916 unsigned long ulAge = 0; 917 if (dircache_find_path(pRes->pdc, szPath, &finfo, &ulAge)) 918 { 919 if (ulAge <= 15) /* @todo configurable. */ 920 { 921 rc = NO_ERROR; 922 finfo.easize = -1; 923 getfindinfoL(pConn, plist, &finfo, 0, NULL); 924 break; 925 } 926 } 927 928 rc = pathparser(pRes, pConn, szPath, path); 929 debuglocal(9, "NdpQueryPathInfo pathparser for <%s> rc=%d\n", path, rc); 930 switch (rc) 931 { 932 case NO_ERROR : 933 case ERROR_FILE_NOT_FOUND: 934 case ERROR_PATH_NOT_FOUND: 935 case ERROR_ACCESS_DENIED: 936 case ERROR_INVALID_PARAMETER: 937 break; 938 default : 939 rc = ERROR_PATH_NOT_FOUND; 940 } 941 942 if (rc) 943 break; 944 945 strncpy(finfo.fname, path, sizeof(finfo.fname) - 1); 946 debuglocal(9, "NdpQueryPathInfo smbwrp_getattr for <%s>\n", path); 947 rc = smbwrp_getattr( &pRes->srv, pConn->cli, &finfo); 948 if (rc) 949 { 950 // remote server not available for first time? 951 if (rc == ERROR_REM_NOT_LIST) 952 { 953 // free current cli resources 954 smbwrp_disconnect( pRes, pConn->cli); 955 // reconnect 956 rcCon = smbwrp_connect( pRes, &pConn->cli); 957 if (rcCon != NO_ERROR) 958 debuglocal(9, "NdpQueryPathInfo smbwrp_connect rc = %d\n", rcCon); 959 // try file list again if reconnecting worked 960 if (rcCon == NO_ERROR) 961 rc = smbwrp_getattr( &pRes->srv, pConn->cli, &finfo); 962 } 963 964 debuglocal(9, "NdpQueryPathInfo smbwrp_getattr, rc = %d\n", rc); 965 switch (rc) 966 { 967 case NO_ERROR : 968 case ERROR_FILE_NOT_FOUND: 969 case ERROR_PATH_NOT_FOUND: 970 case ERROR_ACCESS_DENIED: 971 case ERROR_INVALID_PARAMETER: 972 case ERROR_REM_NOT_LIST: 973 break; 974 default : 975 rc = ERROR_PATH_NOT_FOUND; 976 } 977 } 978 979 if (rc == NO_ERROR) 980 { 981 finfo.easize = -1; 982 getfindinfoL(pConn, plist, &finfo, 0, NULL); 983 } 984 else if (rc == ERROR_FILE_NOT_FOUND) 985 { 986 // now try the upper path 987 char * p = ph->fsphStrRChr(finfo.fname, '\\'); 988 if (p && p > finfo.fname) 989 { 990 *p = 0; 991 rc = smbwrp_getattr( &pRes->srv, pConn->cli, &finfo); 992 debuglocal(9, "NdpQueryPathInfo upper path in <%s>, rc = %d\n", finfo.fname, rc); 993 if (rc == NO_ERROR) 994 rc = (finfo.attr & FILE_DIRECTORY) !=0 ? ERROR_FILE_NOT_FOUND:ERROR_PATH_NOT_FOUND; 995 else if (rc != ERROR_REM_NOT_LIST) 996 rc = ERROR_PATH_NOT_FOUND; 997 } 998 } 999 } while (0); 1000 debuglocal(9, "NdpQueryPathInfo <%s> (%s) %d\n", szPath, path, rc); 1001 1002 LEAVE(); 1003 return rc; 1004 } 1090 1005 1091 1006 int APIENTRY NdpFindStart (HCONNECTION conn, void *plist, NDFILEINFOL *pfiparent, char *szPath, ULONG ulAttribute) 1092 1007 { 1093 Connection *pConn = (Connection *)conn; 1094 Resource *pRes = pConn->pRes; 1095 int rc = NO_ERROR, count = 0; 1096 unsigned long action; 1097 char *mask = "*"; 1098 char dir[CCHMAXPATH+1] = {0}; 1099 char path[CCHMAXPATH+1] = {0}; 1100 smbwrp_fileinfo * data; 1101 NDPATHELEMENT *pel = ph->fsphNameElem(0); 1102 filelist_state state; 1103 char * p; 1104 1105 ENTER(); 1106 1107 debug_printf("NdpFindStart in [%p]\n", pConn); 1108 1109 strncpy(dir, szPath, sizeof(dir) - 1); 1110 if (pel) 1111 { 1112 mask = pel->name; 1113 dir[strlen(szPath) - pel->length] = 0; 1114 } 1115 action = strlen(dir) - 1; 1116 if (dir[action] == '\\') 1117 { 1118 dir[action] = 0; 1119 } 1120 rc = pathparser(pRes, pConn, dir, path); 1121 if (rc) 1122 { 1123 return rc; 1124 } 1125 action = strlen(path) - 1; 1126 if (path[action] != '\\') 1127 { 1128 strncat(path, "\\", sizeof(path) - 1); 1129 } 1130 strcpy(dir, path); 1131 strncat(path, mask, sizeof(path) - 1); 1132 1133 // this structure will be used by libsmb callbacks, so we store here all we need 1134 // to fill netdrive structures 1135 state.pConn = pConn; 1136 state.plist = plist; 1137 state.ulAttribute = ulAttribute; 1138 strcpy( state.dir, dir); 1139 strcpy( state.dir_mask, mask); 1140 strcpy( state.mask, path); 1141 state.fullpath = szPath; 1142 /* This plugin always reads a complete directory listing and filters results 1143 * using actual mask (state.dir_mask) in getfindinfoL. 1144 * May be this was a workaround for some server bug. 1145 * If this will be changed, then directory listing cache must be changed too, 1146 * and must remember the mask, which was used to obtain a listing. 1147 * Now the directory cache saves complete directory listings and then uses them to find 1148 * information about single files. 1149 * However, with a directory cache, it is probably faster to get a full listing and 1150 * then use it to obtain info about separate files than to perform a network 1151 * list query operation using actual wild cards for each file. Some application, 1152 * for example OpenOffice, do this. 1153 */ 1154 p = getlastslash(state.mask); 1155 if (p) 1156 { 1157 *(p + 1) = '*'; 1158 *(p + 2) = 0; 1159 } 1160 else 1161 { 1162 strcpy(state.mask, "\\*"); 1163 } 1164 debuglocal(9,"NdpFindStart: dir [%s], dir_mask [%s], mask [%s], szPath [%s]\n", 1165 state.dir, state.dir_mask, state.mask, state.fullpath); 1166 rc = smbwrp_filelist( &pRes->srv, pConn->cli, &state); 1167 // we need to handle reconnection also here, because NdpQueryPathInfo 1168 // could be called with '*' and exit then immediately (without calling libsmb) 1169 if (rc == ERROR_REM_NOT_LIST) 1170 { 1171 // free current cli resources 1172 smbwrp_disconnect( pRes, pConn->cli); 1173 // reconnect 1174 smbwrp_connect( pRes, &pConn->cli); 1175 // try file list again next loop 1176 rc = smbwrp_filelist( &pRes->srv, pConn->cli, &state); 1177 debuglocal(9,"NdpFindStart remote connection lost, rc = %d\n", rc); 1178 } 1179 1180 debuglocal(9,"NdpFindStart <%s> (%s) cnt %d %d\n", szPath, path, count, rc); 1181 LEAVE(); 1182 return rc; 1008 Connection *pConn = (Connection *)conn; 1009 Resource *pRes = pConn->pRes; 1010 int rc = NO_ERROR, count = 0; 1011 unsigned long action; 1012 char *mask = "*"; 1013 char dir[CCHMAXPATH+1] = {0}; 1014 char path[CCHMAXPATH+1] = {0}; 1015 smbwrp_fileinfo * data; 1016 NDPATHELEMENT *pel = ph->fsphNameElem(0); 1017 filelist_state state; 1018 char * p; 1019 1020 ENTER(); 1021 1022 debuglocal(9, "NdpFindStart in [%p]\n", pConn); 1023 1024 strncpy(dir, szPath, sizeof(dir) - 1); 1025 if (pel) 1026 { 1027 mask = pel->name; 1028 dir[strlen(szPath) - pel->length] = 0; 1029 } 1030 action = strlen(dir) - 1; 1031 if (dir[action] == '\\') 1032 dir[action] = 0; 1033 1034 rc = pathparser(pRes, pConn, dir, path); 1035 if (rc) 1036 return rc; 1037 1038 action = strlen(path) - 1; 1039 if (path[action] != '\\') 1040 strncat(path, "\\", sizeof(path) - 1); 1041 1042 strcpy(dir, path); 1043 strncat(path, mask, sizeof(path) - 1); 1044 1045 /* 1046 * this structure will be used by libsmb callbacks, 1047 * so we store here all we need to fill netdrive structures 1048 */ 1049 state.pConn = pConn; 1050 state.plist = plist; 1051 state.ulAttribute = ulAttribute; 1052 strcpy(state.dir, dir); 1053 strcpy(state.dir_mask, mask); 1054 strcpy(state.mask, path); 1055 state.fullpath = szPath; 1056 /* 1057 * This plugin always reads a complete directory listing and 1058 * filters results using actual mask (state.dir_mask) in getfindinfoL. 1059 * May be this was a workaround for some server bug. 1060 * If this will be changed, then directory listing cache must 1061 * be changed too, and must remember the mask, which was used to 1062 * obtain a listing. Now the directory cache saves complete directory 1063 * listings and then uses them to find information about single files. 1064 * However, with a directory cache, it is probably faster to get a full 1065 * listing and then use it to obtain info about separate files than to 1066 * perform a network list query operation using actual wild cards for 1067 * each file. Some application, for example OpenOffice, do this. 1068 */ 1069 p = getlastslash(state.mask); 1070 if (p) 1071 { 1072 *(p + 1) = '*'; 1073 *(p + 2) = 0; 1074 } 1075 else 1076 strcpy(state.mask, "\\*"); 1077 1078 debuglocal(9, "NdpFindStart: dir [%s], dir_mask [%s], mask [%s], szPath [%s]\n", 1079 state.dir, state.dir_mask, state.mask, state.fullpath); 1080 rc = smbwrp_filelist( &pRes->srv, pConn->cli, &state); 1081 /* 1082 * we need to handle reconnection also here, because NdpQueryPathInfo 1083 * could be called with '*' and exit then immediately 1084 * (without calling libsmb) 1085 */ 1086 if (rc == ERROR_REM_NOT_LIST) 1087 { 1088 // free current cli resources 1089 smbwrp_disconnect( pRes, pConn->cli); 1090 // reconnect 1091 smbwrp_connect( pRes, &pConn->cli); 1092 // try file list again next loop 1093 rc = smbwrp_filelist( &pRes->srv, pConn->cli, &state); 1094 debuglocal(9, "NdpFindStart remote connection lost, rc = %d\n", rc); 1095 } 1096 1097 debuglocal(9, "NdpFindStart <%s> (%s) cnt %d %d\n", szPath, path, count, rc); 1098 1099 LEAVE(); 1100 return rc; 1183 1101 } 1184 1102 1185 1103 int APIENTRY NdpDeletePathInfo (HRESOURCE resource, NDFILEINFOL *pfi) 1186 1104 { 1187 // debuglocal(9,"NdpDeletePathInfo %d\n", 0);1188 1105 debuglocal(9, "NdpDeletePathInfo %d\n", 0); 1106 return NO_ERROR; 1189 1107 } 1190 1108 1191 1109 int APIENTRY NdpRefresh (HCONNECTION conn, char *path, int tree) 1192 1110 { 1193 debuglocal(9,"NdpRefresh <%s> %d\n", path, 0);1194 1111 debuglocal(9, "NdpRefresh <%s> %d\n", path, 0); 1112 return NO_ERROR; 1195 1113 } 1196 1114 1197 1115 int APIENTRY NdpDiscardResourceData (HRESOURCE resource, NDDATABUF *pdatabuf) 1198 1116 { 1199 // The plugin do not have to deallocate anything 1200 // because resource data did not contain any pointers 1201 //to plugins data.1202 // Data stored by fsphSetResourceData will be 1203 // deallocated by NetDrive. 1204 1205 debuglocal(9,"NdpDicardresourceData %d\n", 0);1206 1117 /* 1118 * The plugin do not have to deallocate anything, because 1119 * resource data did not contain any pointers to plugins data. 1120 * Data stored by fsphSetResourceData will be deallocated by NetDrive. 1121 */ 1122 1123 debuglocal(9, "NdpDicardresourceData %d\n", 0); 1124 return NO_ERROR; 1207 1125 } 1208 1126 1209 1127 int APIENTRY NdpSetPathInfo (HCONNECTION conn, NDFILEINFOL *pfi, char *szPathName) 1210 1128 { 1211 Connection *pConn = (Connection *)conn; 1212 Resource *pRes = pConn->pRes; 1213 int rc = 0; 1214 unsigned long action; 1215 char path[CCHMAXPATH+1] = {0}; 1216 smbwrp_fileinfo finfo; 1217 1218 ENTER(); 1219 1220 debug_printf("NdpSetPathInfo in [%p]\n", pConn); 1221 1222 // delete the dir cache 1223 dircache_invalidate(szPathName, pRes->pdc, 1); 1224 1225 do { 1226 rc = pathparser(pRes, pConn, szPathName, path); 1227 if (rc) 1228 { 1229 break; 1230 } 1231 1232 memset(&finfo, 0, sizeof(finfo)); 1233 1234 strncpy(finfo.fname, path, sizeof(finfo.fname) - 1); 1235 fsphDosDateToUnixTime(pfi->stat.fdateLastWrite, pfi->stat.ftimeLastWrite, &(finfo.mtime)); 1236 finfo.attr = pfi->stat.attrFile & 0x37; 1237 rc = smbwrp_setattr(pConn->cli, &finfo); 1238 } while (0); 1239 debuglocal(9,"NdpSetPathInfo <%s> (%s) %d\n", szPathName, path, rc); 1240 LEAVE(); 1241 return rc; 1129 Connection *pConn = (Connection *)conn; 1130 Resource *pRes = pConn->pRes; 1131 int rc = 0; 1132 unsigned long action; 1133 char path[CCHMAXPATH+1] = {0}; 1134 smbwrp_fileinfo finfo; 1135 1136 ENTER(); 1137 1138 debuglocal(9, "NdpSetPathInfo in [%p]\n", pConn); 1139 1140 // delete the dir cache 1141 dircache_invalidate(szPathName, pRes->pdc, 1); 1142 1143 do { 1144 rc = pathparser(pRes, pConn, szPathName, path); 1145 if (rc) 1146 break; 1147 1148 memset(&finfo, 0, sizeof(finfo)); 1149 strncpy(finfo.fname, path, sizeof(finfo.fname) - 1); 1150 fsphDosDateToUnixTime(pfi->stat.fdateLastWrite, pfi->stat.ftimeLastWrite, &(finfo.mtime)); 1151 finfo.attr = pfi->stat.attrFile & 0x37; 1152 rc = smbwrp_setattr(pConn->cli, &finfo); 1153 } while (0); 1154 1155 debuglocal(9, "NdpSetPathInfo <%s> (%s) %d\n", szPathName, path, rc); 1156 1157 LEAVE(); 1158 return rc; 1242 1159 } 1243 1160 1244 1161 int buildFEALIST(FEALIST *pFEASrc, GEALIST *pGEAList, FEALIST *pFEAList) 1245 1162 { 1246 int rc = 0; 1247 FEA * pfea; 1248 FEA * pfeadest; 1249 unsigned long size, done = sizeof(pFEAList->cbList), dsize, ddone = sizeof(pFEAList->cbList); 1250 1251 size = pFEASrc->cbList; 1252 pfea = pFEASrc->list; 1253 pfeadest = pFEAList->list; 1254 dsize = pFEAList->cbList; 1255 //debuglocal(9,"buildFEALIST in destsize %d srcsize %d pGEAList=%08x pGEAList->cbList=%d\n", dsize, ddone, size, pGEAList, pGEAList ? pGEAList->cbList : 0); 1256 while (done < size) 1257 { 1258 char * name = (char *)(pfea + 1); 1259 int insert = 1; 1260 if (pGEAList && pGEAList->cbList > sizeof(pGEAList->cbList)) 1261 { 1262 GEA * pgea = pGEAList->list; 1263 unsigned long size = pGEAList->cbList - sizeof(pGEAList->cbList), done = 0; 1264 insert = 0; 1265 while (done < size) 1266 { 1267 //debuglocal(9,"comp <%s> <%s>\n", name, pgea->szName); 1268 if (!ph->fsphStrNCmp(name, pgea->szName, pgea->cbName)) 1269 { 1270 insert = 1; 1271 break; 1272 } 1273 done += pgea->cbName + 2; 1274 pgea = (GEA *)((char *)pgea + pgea->cbName + 2); 1275 } 1276 } 1277 if (insert) 1278 { 1279 ddone += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue; 1280 if (ddone <= dsize) 1281 { 1282 pfeadest->cbName = pfea->cbName; 1283 pfeadest->cbValue = pfea->cbValue; 1284 pfeadest->fEA = 0; 1285 strcpy((char *)(pfeadest + 1), name); 1286 memcpy((char *)(pfeadest + 1) + pfea->cbName + 1, (char *)(pfea + 1) + pfea->cbName + 1, pfea->cbValue); 1287 pfeadest = (FEA *)((char *)pFEAList + ddone); 1288 } 1289 } 1290 done += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue; 1291 //debuglocal(9,"buuildfea <%s> insert=%d pfea->cbName=%d pfea->cbValue=%d srcdone=%d destdone=%d pfeadest=%08x pfea=%08x\n", name, insert, pfea->cbName, pfea->cbValue, done, ddone, pfeadest, pfea); 1292 pfea = (FEA *)((char *)pFEASrc + done); 1293 } 1294 pFEAList->cbList = ddone; 1295 if (ddone > dsize && dsize > sizeof(pFEAList->cbList)) 1296 { 1297 rc = ERROR_BUFFER_OVERFLOW; 1298 } 1299 debuglocal(9,"buildFEALIST rc=%d destsize=%d destdone=%d srcsize=%d pGEAList=%08x\n", rc, dsize, ddone, size, pGEAList); 1300 return rc; 1163 int rc = 0; 1164 FEA * pfea; 1165 FEA * pfeadest; 1166 unsigned long size; 1167 unsigned long done = sizeof(pFEAList->cbList); 1168 unsigned long dsize; 1169 unsigned long ddone = sizeof(pFEAList->cbList); 1170 1171 size = pFEASrc->cbList; 1172 pfea = pFEASrc->list; 1173 pfeadest = pFEAList->list; 1174 dsize = pFEAList->cbList; 1175 //debuglocal(9,"buildFEALIST in destsize %d srcsize %d pGEAList=%08x pGEAList->cbList=%d\n", dsize, ddone, size, pGEAList, pGEAList ? pGEAList->cbList : 0); 1176 1177 while (done < size) 1178 { 1179 char * name = (char *)(pfea + 1); 1180 int insert = 1; 1181 if (pGEAList && pGEAList->cbList > sizeof(pGEAList->cbList)) 1182 { 1183 GEA * pgea = pGEAList->list; 1184 unsigned long size = pGEAList->cbList - sizeof(pGEAList->cbList); 1185 unsigned long done = 0; 1186 insert = 0; 1187 while (done < size) 1188 { 1189 //debuglocal(9,"comp <%s> <%s>\n", name, pgea->szName); 1190 if (!ph->fsphStrNCmp(name, pgea->szName, pgea->cbName)) 1191 { 1192 insert = 1; 1193 break; 1194 } 1195 done += pgea->cbName + 2; 1196 pgea = (GEA *)((char *)pgea + pgea->cbName + 2); 1197 } 1198 } 1199 if (insert) 1200 { 1201 ddone += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue; 1202 if (ddone <= dsize) 1203 { 1204 pfeadest->cbName = pfea->cbName; 1205 pfeadest->cbValue = pfea->cbValue; 1206 pfeadest->fEA = 0; 1207 strcpy((char *)(pfeadest + 1), name); 1208 memcpy((char *)(pfeadest + 1) + pfea->cbName + 1, (char *)(pfea + 1) + pfea->cbName + 1, pfea->cbValue); 1209 pfeadest = (FEA *)((char *)pFEAList + ddone); 1210 } 1211 } 1212 done += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue; 1213 //debuglocal(9,"buuildfea <%s> insert=%d pfea->cbName=%d pfea->cbValue=%d srcdone=%d destdone=%d pfeadest=%08x pfea=%08x\n", name, insert, pfea->cbName, pfea->cbValue, done, ddone, pfeadest, pfea); 1214 pfea = (FEA *)((char *)pFEASrc + done); 1215 } 1216 1217 pFEAList->cbList = ddone; 1218 if (ddone > dsize && dsize > sizeof(pFEAList->cbList)) 1219 rc = ERROR_BUFFER_OVERFLOW; 1220 1221 debuglocal(9, "buildFEALIST rc=%d destsize=%d destdone=%d srcsize=%d pGEAList=%08x\n", rc, dsize, ddone, size, pGEAList); 1222 return rc; 1301 1223 } 1302 1224 1303 1225 int APIENTRY NdpEAQuery (HCONNECTION conn, GEALIST *pGEAList, NDFILEINFOL *pfi, FEALIST *pFEAList) 1304 1226 { 1305 Connection *pConn = (Connection *)conn; 1306 Resource *pRes = pConn->pRes; 1307 int rc = 0; 1308 unsigned long action; 1309 char * path = NULL; 1310 FEALIST * pFEASrc; 1311 NDDATABUF fdata = {0}; 1312 smbwrp_fileinfo *finfo; 1313 const int cbBuffer = 64*1024; 1314 1315 if (!pfi || !pfi->pszName || !pFEAList) 1316 { 1317 return ERROR_EAS_NOT_SUPPORTED; 1318 } 1319 if (!pRes->easupport) 1320 { 1321 return ERROR_EAS_NOT_SUPPORTED; 1322 } 1323 1324 rc = ph->fsphGetFileInfoData(pfi, &fdata, 0); 1325 if (rc || !fdata.ulSize || !fdata.pData) 1326 { 1327 debuglocal(9,"NdpEAQuery: ph->fsphGetFileInfoData = %d/%d %08x\n", rc, fdata.ulSize, fdata.pData); 1328 return ERROR_EAS_NOT_SUPPORTED; 1329 } 1330 1331 ENTER(); 1332 1333 finfo = (smbwrp_fileinfo *)fdata.pData; 1334 path = finfo->fname; 1335 1336 debuglocal(9,"NdpEAQuery in [%p] <%s> %08x %d\n", pConn, path, pGEAList, pGEAList ? pGEAList->cbList : 0); 1337 1338 char *pchBuffer = (char *)malloc(cbBuffer); 1339 if (!pchBuffer) 1340 { 1341 LEAVE(); 1342 return ERROR_NOT_ENOUGH_MEMORY; 1343 } 1344 1345 do { 1346 rc = smbwrp_listea( pConn->cli, path, pchBuffer, cbBuffer); 1347 pFEASrc = (FEALIST*) pchBuffer; 1348 if (rc) 1349 { 1350 //rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER); 1351 switch (rc) 1352 { 1353 case ERROR_FILE_NOT_FOUND : 1354 case ERROR_PATH_NOT_FOUND : 1355 { 1356 pFEAList->cbList = sizeof(pFEAList->cbList); 1357 rc = NO_ERROR; 1358 } break; 1359 case ERROR_BUFFER_OVERFLOW : 1360 { 1361 pFEAList->cbList = pFEASrc->cbList; 1362 } break; 1363 default : 1364 { 1365 rc = ERROR_EAS_NOT_SUPPORTED; 1366 } 1367 } 1368 } 1369 else 1370 { 1371 rc = buildFEALIST((FEALIST *)pFEASrc, pGEAList, pFEAList); 1372 } 1373 } while (0); 1374 free(pchBuffer); 1375 debuglocal(9,"NdpEAQuery <%s> %d %d %d\n", pfi->pszName, rc, pFEASrc->cbList, pFEAList->cbList); 1376 LEAVE(); 1377 return rc; 1227 Connection *pConn = (Connection *)conn; 1228 Resource *pRes = pConn->pRes; 1229 int rc = 0; 1230 unsigned long action; 1231 char * path = NULL; 1232 FEALIST * pFEASrc; 1233 NDDATABUF fdata = {0}; 1234 smbwrp_fileinfo *finfo; 1235 const int cbBuffer = 64*1024; 1236 1237 if (!pfi || !pfi->pszName || !pFEAList) 1238 return ERROR_EAS_NOT_SUPPORTED; 1239 1240 if (!pRes->easupport) 1241 return ERROR_EAS_NOT_SUPPORTED; 1242 1243 rc = ph->fsphGetFileInfoData(pfi, &fdata, 0); 1244 if (rc || !fdata.ulSize || !fdata.pData) 1245 { 1246 debuglocal(9, "NdpEAQuery: ph->fsphGetFileInfoData = %d/%d %08x\n", rc, fdata.ulSize, fdata.pData); 1247 return ERROR_EAS_NOT_SUPPORTED; 1248 } 1249 1250 ENTER(); 1251 1252 finfo = (smbwrp_fileinfo *)fdata.pData; 1253 path = finfo->fname; 1254 debuglocal(9, "NdpEAQuery in [%p] <%s> %08x %d\n", pConn, path, pGEAList, pGEAList ? pGEAList->cbList : 0); 1255 1256 char *pchBuffer = (char *)malloc(cbBuffer); 1257 if (!pchBuffer) 1258 { 1259 LEAVE(); 1260 return ERROR_NOT_ENOUGH_MEMORY; 1261 } 1262 1263 do { 1264 rc = smbwrp_listea( pConn->cli, path, pchBuffer, cbBuffer); 1265 pFEASrc = (FEALIST*) pchBuffer; 1266 if (rc) 1267 { 1268 switch (rc) 1269 { 1270 case ERROR_FILE_NOT_FOUND : 1271 case ERROR_PATH_NOT_FOUND : 1272 pFEAList->cbList = sizeof(pFEAList->cbList); 1273 rc = NO_ERROR; 1274 break; 1275 case ERROR_BUFFER_OVERFLOW : 1276 pFEAList->cbList = pFEASrc->cbList; 1277 break; 1278 default : 1279 rc = ERROR_EAS_NOT_SUPPORTED; 1280 } 1281 } 1282 else 1283 rc = buildFEALIST((FEALIST *)pFEASrc, pGEAList, pFEAList); 1284 } while (0); 1285 1286 free(pchBuffer); 1287 debuglocal(9, "NdpEAQuery <%s> %d %d %d\n", pfi->pszName, rc, pFEASrc->cbList, pFEAList->cbList); 1288 1289 LEAVE(); 1290 return rc; 1378 1291 } 1379 1292 1380 1293 int APIENTRY NdpEASet (HCONNECTION conn, FEALIST *pFEAList, NDFILEINFOL *pfi) 1381 1294 { 1382 Connection *pConn = (Connection *)conn; 1383 Resource *pRes = pConn->pRes; 1384 int rc = 0; 1385 char * path; 1386 unsigned long action; 1387 NDDATABUF fdata = {0}; 1388 smbwrp_fileinfo *finfo; 1389 1390 debuglocal(9,"NdpEASet in [%p]\n", pConn); 1391 1392 if (!pfi || !pfi->pszName) 1393 { 1394 return ERROR_EAS_NOT_SUPPORTED; 1395 } 1396 if (!pRes->easupport) 1397 { 1398 return ERROR_EAS_NOT_SUPPORTED; 1399 } 1400 1401 rc = ph->fsphGetFileInfoData(pfi, &fdata, 0); 1402 if (rc || !fdata.ulSize || !fdata.pData) 1403 { 1404 debuglocal(9,"NdpEASet: ph->fsphGetFileInfoData = %d/%d/%08x\n", rc, fdata.ulSize, fdata.pData); 1405 return ERROR_EAS_NOT_SUPPORTED; 1406 } 1407 1408 finfo = (smbwrp_fileinfo *)fdata.pData; 1409 path = finfo->fname; 1410 1411 rc = helperEASet(pConn->cli, pFEAList, path); 1412 debuglocal(9,"NdpEASet %d\n", rc); 1413 return rc; 1295 Connection *pConn = (Connection *)conn; 1296 Resource *pRes = pConn->pRes; 1297 int rc = 0; 1298 char * path; 1299 unsigned long action; 1300 NDDATABUF fdata = {0}; 1301 smbwrp_fileinfo *finfo; 1302 1303 debuglocal(9, "NdpEASet in [%p]\n", pConn); 1304 1305 if (!pfi || !pfi->pszName) 1306 return ERROR_EAS_NOT_SUPPORTED; 1307 1308 if (!pRes->easupport) 1309 return ERROR_EAS_NOT_SUPPORTED; 1310 1311 rc = ph->fsphGetFileInfoData(pfi, &fdata, 0); 1312 if (rc || !fdata.ulSize || !fdata.pData) 1313 { 1314 debuglocal(9, "NdpEASet: ph->fsphGetFileInfoData = %d/%d/%08x\n", rc, fdata.ulSize, fdata.pData); 1315 return ERROR_EAS_NOT_SUPPORTED; 1316 } 1317 1318 finfo = (smbwrp_fileinfo *)fdata.pData; 1319 path = finfo->fname; 1320 1321 rc = helperEASet(pConn->cli, pFEAList, path); 1322 debuglocal(9, "NdpEASet %d\n", rc); 1323 return rc; 1414 1324 } 1415 1325 1416 1326 int APIENTRY NdpEASize (HCONNECTION conn, NDFILEINFOL *pfi, ULONG *pulEASize) 1417 1327 { 1418 Connection *pConn = (Connection *)conn; 1419 Resource *pRes = pConn->pRes; 1420 int rc = 0; 1421 unsigned long action; 1422 char * path = NULL; 1423 FEALIST * pfealist; 1424 NDDATABUF fdata = {0}; 1425 smbwrp_fileinfo *finfo; 1426 const int cbBuffer = 64*1024; 1427 int easize; 1428 1429 if (!pfi || !pulEASize) 1430 { 1431 return ERROR_EAS_NOT_SUPPORTED; 1432 } 1433 if (!pRes->easupport) 1434 { 1435 return ERROR_EAS_NOT_SUPPORTED; 1436 } 1437 1438 rc = ph->fsphGetFileInfoData(pfi, &fdata, 0); 1439 if (rc || !fdata.ulSize || !fdata.pData) 1440 { 1441 debuglocal(9,"NdpEASize: ph->fsphGetFileInfoData = %d/%d/%08x\n", rc, fdata.ulSize, fdata.pData); 1442 return ERROR_EAS_NOT_SUPPORTED; 1443 } 1444 1445 ENTER(); 1446 1447 finfo = (smbwrp_fileinfo *)fdata.pData; 1448 easize = finfo->easize; 1449 finfo->easize = -1; 1450 path = finfo->fname; 1451 if (easize >= 0) 1452 { 1453 *pulEASize = easize; 1454 debuglocal(9,"NdpEASize <%s> cached %d\n", path, easize); 1455 LEAVE(); 1456 return NO_ERROR; 1457 } 1458 1459 debuglocal(9,"NdpEASize in [%p] <%s> \n", pConn, path); 1460 1461 char *pchBuffer = (char *)malloc(cbBuffer); 1462 if (!pchBuffer) 1463 { 1464 LEAVE(); 1465 return ERROR_NOT_ENOUGH_MEMORY; 1466 } 1467 1468 do { 1469 rc = smbwrp_listea(pConn->cli, path, pchBuffer, cbBuffer); 1470 pfealist = (FEALIST*)pchBuffer; 1471 if (rc) 1472 { 1473 //rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER); 1474 switch (rc) 1475 { 1476 case ERROR_FILE_NOT_FOUND : 1477 case ERROR_PATH_NOT_FOUND : 1478 { 1479 pfealist->cbList = sizeof(pfealist->cbList); 1480 } /* Fall through */ 1481 case ERROR_BUFFER_OVERFLOW : 1482 { 1483 rc = NO_ERROR; 1484 } break; 1485 default : 1486 { 1487 rc = ERROR_EAS_NOT_SUPPORTED; 1488 } 1489 } 1490 } 1491 *pulEASize = pfealist->cbList; 1492 } while (0); 1493 free(pchBuffer); 1494 debuglocal(9,"NdpEASize <%s> %d %d\n", pfi->pszName, *pulEASize, rc); 1495 LEAVE(); 1496 return rc; 1328 Connection *pConn = (Connection *)conn; 1329 Resource *pRes = pConn->pRes; 1330 int rc = 0; 1331 unsigned long action; 1332 char * path = NULL; 1333 FEALIST * pfealist; 1334 NDDATABUF fdata = {0}; 1335 smbwrp_fileinfo *finfo; 1336 const int cbBuffer = 64*1024; 1337 int easize; 1338 1339 if (!pfi || !pulEASize) 1340 return ERROR_EAS_NOT_SUPPORTED; 1341 1342 if (!pRes->easupport) 1343 return ERROR_EAS_NOT_SUPPORTED; 1344 1345 rc = ph->fsphGetFileInfoData(pfi, &fdata, 0); 1346 if (rc || !fdata.ulSize || !fdata.pData) 1347 { 1348 debuglocal(9, "NdpEASize: ph->fsphGetFileInfoData = %d/%d/%08x\n", rc, fdata.ulSize, fdata.pData); 1349 return ERROR_EAS_NOT_SUPPORTED; 1350 } 1351 1352 ENTER(); 1353 1354 finfo = (smbwrp_fileinfo *)fdata.pData; 1355 easize = finfo->easize; 1356 finfo->easize = -1; 1357 path = finfo->fname; 1358 if (easize >= 0) 1359 { 1360 *pulEASize = easize; 1361 debuglocal(9, "NdpEASize <%s> cached %d\n", path, easize); 1362 LEAVE(); 1363 return NO_ERROR; 1364 } 1365 1366 debuglocal(9, "NdpEASize in [%p] <%s> \n", pConn, path); 1367 1368 char *pchBuffer = (char *)malloc(cbBuffer); 1369 if (!pchBuffer) 1370 { 1371 LEAVE(); 1372 return ERROR_NOT_ENOUGH_MEMORY; 1373 } 1374 1375 do { 1376 rc = smbwrp_listea(pConn->cli, path, pchBuffer, cbBuffer); 1377 pfealist = (FEALIST*)pchBuffer; 1378 if (rc) 1379 { 1380 switch (rc) 1381 { 1382 case ERROR_FILE_NOT_FOUND : 1383 case ERROR_PATH_NOT_FOUND : 1384 pfealist->cbList = sizeof(pfealist->cbList); // Fall through */ 1385 case ERROR_BUFFER_OVERFLOW : 1386 rc = NO_ERROR; 1387 break; 1388 default : 1389 rc = ERROR_EAS_NOT_SUPPORTED; 1390 } 1391 } 1392 *pulEASize = pfealist->cbList; 1393 } while (0); 1394 1395 free(pchBuffer); 1396 debuglocal(9, "NdpEASize <%s> %d %d\n", pfi->pszName, *pulEASize, rc); 1397 1398 LEAVE(); 1399 return rc; 1497 1400 } 1498 1401 1499 1402 int APIENTRY NdpSetCurrentDir (HCONNECTION conn, NDFILEINFOL *pfi, char *szPath) 1500 1403 { 1501 1502 1503 1504 1505 1404 Connection *pConn = (Connection *)conn; 1405 Resource *pRes = pConn->pRes; 1406 int rc = 0; 1407 unsigned long action; 1408 char path[CCHMAXPATH+1] = {0}; 1506 1409 1507 debuglocal(9,"NdpSetCurrentDir in [%p]\n", pConn);1508 1509 1510 1511 1512 1513 1514 { 1515 break; 1516 } 1517 1518 rc = smbwrp_chdir(&pRes->srv, pConn->cli, path); 1519 } while (0);1520 debuglocal(9,"NdpSetCurrentDir <%s> (%s) %d\n", szPath, path, rc); 1521 1522 1410 debuglocal(9, "NdpSetCurrentDir in [%p]\n", pConn); 1411 1412 ENTER(); 1413 1414 do { 1415 rc = pathparser(pRes, pConn, szPath, path); 1416 if (rc) 1417 break; 1418 1419 rc = smbwrp_chdir(&pRes->srv, pConn->cli, path); 1420 } while (0); 1421 1422 debuglocal(9, "NdpSetCurrentDir <%s> (%s) %d\n", szPath, path, rc); 1423 1424 LEAVE(); 1425 return rc; 1523 1426 } 1524 1427 1525 1428 int APIENTRY NdpCopy (HCONNECTION conn, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, ULONG ulOption) 1526 1429 { 1527 debuglocal(9,"NdpCopy <%s> -> <%s> %d\n", szSrc, szDst, ERROR_CANNOT_COPY);1528 1430 debuglocal(9, "NdpCopy <%s> -> <%s> %d\n", szSrc, szDst, ERROR_CANNOT_COPY); 1431 return ERROR_CANNOT_COPY; 1529 1432 } 1530 1433 1531 1434 int APIENTRY NdpCopy2 (HCONNECTION conn, HRESOURCE resDst, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, ULONG ulOption) 1532 1435 { 1533 debuglocal(9,"NdpCopy2 <%s> -> <%s> %d\n", szSrc, szDst, ERROR_CANNOT_COPY);1534 1436 debuglocal(9, "NdpCopy2 <%s> -> <%s> %d\n", szSrc, szDst, ERROR_CANNOT_COPY); 1437 return ERROR_CANNOT_COPY; 1535 1438 } 1536 1439 1537 1440 int APIENTRY NdpForceDelete (HCONNECTION conn, NDFILEINFOL *pfi, char *szFile) 1538 1441 { 1539 1540 1541 1542 1543 1544 1545 1546 1547 debuglocal(9,"NdpForceDelete in [%p]\n", pConn);1548 1549 1550 1551 1552 1553 1554 { 1555 break; 1556 } 1557 1558 rc = smbwrp_unlink(pConn->cli, path); 1559 } while (0);1560 debuglocal(9,"NdpForceDelete <%s> (%s) %d\n", szFile, path, rc); 1561 1562 1442 Connection *pConn = (Connection *)conn; 1443 Resource *pRes = pConn->pRes; 1444 int rc = 0; 1445 unsigned long action; 1446 char path[CCHMAXPATH+1] = {0}; 1447 1448 ENTER(); 1449 1450 debuglocal(9, "NdpForceDelete in [%p]\n", pConn); 1451 1452 dircache_invalidate(szFile, pRes->pdc, 1); 1453 1454 do { 1455 rc = pathparser(pRes, pConn, szFile, path); 1456 if (rc) 1457 break; 1458 1459 rc = smbwrp_unlink(pConn->cli, path); 1460 } while (0); 1461 1462 debuglocal(9, "NdpForceDelete <%s> (%s) %d\n", szFile, path, rc); 1463 1464 LEAVE(); 1465 return rc; 1563 1466 } 1564 1467 1565 1468 int APIENTRY NdpCreateDir (HCONNECTION conn, NDFILEINFOL *pfiparent, char *szDirName, FEALIST *pFEAList) 1566 1469 { 1567 Connection *pConn = (Connection *)conn; 1568 Resource *pRes = pConn->pRes; 1569 int rc = 0; 1570 int rcEASet = 0; 1571 unsigned long action; 1572 char path[CCHMAXPATH+1] = {0}; 1573 1574 ENTER(); 1575 1576 debuglocal(9,"NdpCreateDir in [%p]\n", pConn); 1577 1578 dircache_invalidate(szDirName, pRes->pdc, 1); 1579 1580 do { 1581 rc = pathparser(pRes, pConn, szDirName, path); 1582 if (rc) 1583 { 1584 break; 1585 } 1586 1587 rc = smbwrp_mkdir(pConn->cli, path); 1588 } while (0); 1589 LEAVE(); 1590 1591 if (path && pRes->easupport) 1592 { 1593 rcEASet = helperEASet(pConn->cli, pFEAList, path); 1594 } 1595 debuglocal(9,"NdpCreateDir <%s> (%s) rc=%d, EASupport=%s rc=%d\n", szDirName, path, rc, pRes->easupport?"yes":"no", rcEASet); 1596 1597 return rc; 1470 Connection *pConn = (Connection *)conn; 1471 Resource *pRes = pConn->pRes; 1472 int rc = 0; 1473 int rcEASet = 0; 1474 unsigned long action; 1475 char path[CCHMAXPATH+1] = {0}; 1476 1477 ENTER(); 1478 1479 debuglocal(9, "NdpCreateDir in [%p]\n", pConn); 1480 1481 dircache_invalidate(szDirName, pRes->pdc, 1); 1482 1483 do { 1484 rc = pathparser(pRes, pConn, szDirName, path); 1485 if (rc) 1486 break; 1487 1488 rc = smbwrp_mkdir(pConn->cli, path); 1489 } while (0); 1490 1491 LEAVE(); 1492 1493 if (path && pRes->easupport) 1494 rcEASet = helperEASet(pConn->cli, pFEAList, path); 1495 1496 debuglocal(9, "NdpCreateDir <%s> (%s) rc=%d, EASupport=%s rc=%d\n", szDirName, path, rc, pRes->easupport?"yes":"no", rcEASet); 1497 1498 return rc; 1598 1499 } 1599 1500 1600 1501 int APIENTRY NdpDeleteDir (HCONNECTION conn, NDFILEINFOL *pfi, char *szDir) 1601 1502 { 1602 1603 1604 1605 1606 1607 1608 1609 1610 debuglocal(9,"NdpDeleteDir in [%p]\n", pConn);1611 1612 1613 1614 1615 1616 1617 { 1618 break; 1619 } 1620 1621 rc = smbwrp_rmdir(pConn->cli, path); 1622 } while (0);1623 debuglocal(9,"NdpDeleteDir <%s> (%s) %d\n", szDir, path, rc); 1624 1625 1503 Connection *pConn = (Connection *)conn; 1504 Resource *pRes = pConn->pRes; 1505 int rc = 0; 1506 unsigned long action; 1507 char path[CCHMAXPATH+1] = {0}; 1508 1509 ENTER(); 1510 1511 debuglocal(9, "NdpDeleteDir in [%p]\n", pConn); 1512 1513 dircache_invalidate(szDir, pRes->pdc, 1); 1514 1515 do { 1516 rc = pathparser(pRes, pConn, szDir, path); 1517 if (rc) 1518 break; 1519 1520 rc = smbwrp_rmdir(pConn->cli, path); 1521 } while (0); 1522 1523 debuglocal(9, "NdpDeleteDir <%s> (%s) %d\n", szDir, path, rc); 1524 1525 LEAVE(); 1526 return rc; 1626 1527 } 1627 1528 1628 1529 int APIENTRY NdpMove (HCONNECTION conn, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc) 1629 1530 { 1630 Connection *pConn = (Connection *)conn; 1631 Resource *pRes = pConn->pRes; 1632 int rc = 0; 1633 unsigned long action; 1634 char src[CCHMAXPATH+1] = {0}; 1635 int l1, l2; 1636 char * p = szDst; 1637 1638 ENTER(); 1639 1640 debuglocal(9,"NdpMove in [%p] from <%s> to <%s>\n", pConn, szSrc, szDst); 1641 1642 dircache_invalidate(szSrc, pRes->pdc, 1); 1643 dircache_invalidate(szDst, pRes->pdc, 1); 1644 1645 do 1646 { 1647 rc = pathparser(pRes, pConn, szSrc, src); 1648 if (rc) 1649 { 1650 break; 1651 } 1652 l1 = strlen(szSrc); 1653 l2 = strlen(src); 1654 if (l1 > l2) 1655 { 1656 if (ph->fsphStrNICmp(szSrc, szDst, l1 - l2)) 1657 { 1658 // the file moved accross different shares or servers or workgroups 1659 rc = ERROR_WRITE_PROTECT; 1660 break; 1661 } 1662 p = szDst + l1 - l2 + 1; 1663 } 1664 //pConn->mem[CCHMAXPATH + 1] = '\\'; 1665 rc = smbwrp_rename(pConn->cli, src, p); 1666 } while (0); 1667 debuglocal(9,"NdpMove <%s> -> <%s> (%s) %d\n", szSrc, szDst, src, rc); 1668 LEAVE(); 1669 return rc; 1531 Connection *pConn = (Connection *)conn; 1532 Resource *pRes = pConn->pRes; 1533 int rc = 0; 1534 unsigned long action; 1535 char src[CCHMAXPATH+1] = {0}; 1536 int l1, l2; 1537 char * p = szDst; 1538 1539 ENTER(); 1540 1541 debuglocal(9, "NdpMove in [%p] from <%s> to <%s>\n", pConn, szSrc, szDst); 1542 1543 dircache_invalidate(szSrc, pRes->pdc, 1); 1544 dircache_invalidate(szDst, pRes->pdc, 1); 1545 1546 do 1547 { 1548 rc = pathparser(pRes, pConn, szSrc, src); 1549 if (rc) 1550 break; 1551 1552 l1 = strlen(szSrc); 1553 l2 = strlen(src); 1554 if (l1 > l2) 1555 { 1556 if (ph->fsphStrNICmp(szSrc, szDst, l1 - l2)) 1557 { 1558 /* 1559 * the file moved accross different shares or servers or 1560 * workgroups 1561 */ 1562 rc = ERROR_WRITE_PROTECT; 1563 break; 1564 } 1565 p = szDst + l1 - l2 + 1; 1566 } 1567 rc = smbwrp_rename(pConn->cli, src, p); 1568 } while (0); 1569 1570 debuglocal(9, "NdpMove <%s> -> <%s> (%s) %d\n", szSrc, szDst, src, rc); 1571 1572 LEAVE(); 1573 return rc; 1670 1574 } 1671 1575 1672 1576 int APIENTRY NdpMove2 (HCONNECTION conn, HRESOURCE resDst, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc) 1673 1577 { 1674 debuglocal(9,"NdpMove2 <%s> -> <%s> %d\n", szSrc, szDst, ERROR_WRITE_PROTECT);1675 1578 debuglocal(9, "NdpMove2 <%s> -> <%s> %d\n", szSrc, szDst, ERROR_WRITE_PROTECT); 1579 return ERROR_WRITE_PROTECT; 1676 1580 } 1677 1581 … … 1679 1583 int APIENTRY NdpChangeCase (HCONNECTION conn, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, char *szNewName, ULONG ulNameLen) 1680 1584 { 1681 1585 return NdpMove (conn, pfiSrc, szDst, pfiSrc, szSrc); 1682 1586 } 1683 1587 1684 1588 int APIENTRY NdpRename (HCONNECTION conn, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, char *szNewName, ULONG ulNameLen) 1685 1589 { 1686 1590 return NdpMove (conn, pfiSrc, szDst, pfiSrc, szSrc); 1687 1591 } 1688 1592 1689 1593 int smbopen(Connection *pConn, char *szFileName, int flags, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList) 1690 1594 { 1691 Resource *pRes = pConn->pRes; 1692 unsigned long action; 1693 int rc = 0; 1694 char path[CCHMAXPATH+1] = {0}; 1695 1696 ENTER(); 1697 1698 debuglocal(9,"smbopen in [%p] %d\n", pConn, pConn->file.fd); 1699 1700 if (flags & O_CREAT) 1701 { 1702 dircache_invalidate(szFileName, pRes->pdc, 1); 1703 } 1704 do { 1705 if (pConn->file.fd > 0) 1706 { 1707 rc = ERROR_TOO_MANY_OPEN_FILES; 1708 break; 1709 } 1710 1711 rc = pathparser(pRes, pConn, szFileName, path); 1712 if (rc) 1713 { 1714 break; 1715 } 1716 1717 strncpy(pConn->file.fullname, szFileName, sizeof(pConn->file.fullname) - 1); 1718 strncpy(pConn->file.fname, path, sizeof(pConn->file.fname) - 1); 1719 flags |= O_BINARY; 1720 switch (ulOpenMode & 3) 1721 { 1722 case OPEN_ACCESS_READONLY : flags |= O_RDONLY; break; 1723 case OPEN_ACCESS_WRITEONLY : flags |= O_WRONLY; break; 1724 case OPEN_ACCESS_READWRITE : flags |= O_RDWR; break; 1725 default : flags |= O_RDWR; 1726 } 1727 pConn->file.openmode = flags; 1728 pConn->file.openattr = ulAttribute & 0x37; 1729 pConn->file.denymode = (ulOpenMode & 0x70) >> 4; 1730 rc = smbwrp_open(pConn->cli, &pConn->file); 1731 } while (0); 1732 debuglocal(9,"smbopen <%s> (%s) %08x %08x %08x %d. file = %d\n", szFileName, path, flags, ulOpenMode, ulAttribute, rc, pConn->file.fd); 1733 if (!rc && pFEAList) 1734 { 1735 int rc1 = NdpFileEASet((HCONNECTION)pConn, (NDFILEHANDLE)0, pFEAList); 1736 debuglocal(9,"smbopen NdpFileEASet %d. pFEAList->cbList %d\n", rc1, pFEAList->cbList); 1737 } 1738 LEAVE(); 1739 return rc; 1595 Resource *pRes = pConn->pRes; 1596 unsigned long action; 1597 int rc = 0; 1598 char path[CCHMAXPATH+1] = {0}; 1599 1600 ENTER(); 1601 1602 debuglocal(9, "smbopen in [%p] %d\n", pConn, pConn->file.fd); 1603 1604 if (flags & O_CREAT) 1605 dircache_invalidate(szFileName, pRes->pdc, 1); 1606 1607 do { 1608 if (pConn->file.fd > 0) 1609 { 1610 rc = ERROR_TOO_MANY_OPEN_FILES; 1611 break; 1612 } 1613 1614 rc = pathparser(pRes, pConn, szFileName, path); 1615 if (rc) 1616 break; 1617 1618 strncpy(pConn->file.fullname, szFileName, sizeof(pConn->file.fullname) - 1); 1619 strncpy(pConn->file.fname, path, sizeof(pConn->file.fname) - 1); 1620 flags |= O_BINARY; 1621 switch (ulOpenMode & 3) 1622 { 1623 case OPEN_ACCESS_READONLY : 1624 flags |= O_RDONLY; 1625 break; 1626 case OPEN_ACCESS_WRITEONLY : 1627 flags |= O_WRONLY; 1628 break; 1629 case OPEN_ACCESS_READWRITE : 1630 flags |= O_RDWR; 1631 break; 1632 default : 1633 flags |= O_RDWR; 1634 } 1635 1636 pConn->file.openmode = flags; 1637 pConn->file.openattr = ulAttribute & 0x37; 1638 pConn->file.denymode = (ulOpenMode & 0x70) >> 4; 1639 rc = smbwrp_open(pConn->cli, &pConn->file); 1640 } while (0); 1641 1642 debuglocal(9, "smbopen <%s> (%s) %08x %08x %08x %d. file = %d\n", szFileName, path, flags, ulOpenMode, ulAttribute, rc, pConn->file.fd); 1643 if (!rc && pFEAList) 1644 { 1645 int rc1 = NdpFileEASet((HCONNECTION)pConn, (NDFILEHANDLE)0, pFEAList); 1646 debuglocal(9, "smbopen NdpFileEASet %d. pFEAList->cbList %d\n", rc1, pFEAList->cbList); 1647 } 1648 1649 LEAVE(); 1650 return rc; 1740 1651 } 1741 1652 1742 1653 int APIENTRY NdpOpenReplace (HCONNECTION conn, NDFILEINFOL *pfi, NDFILEHANDLE *phandle, char *szFileName, ULONG ulSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList) 1743 1654 { 1744 1655 return smbopen((Connection *)conn, szFileName, O_TRUNC, ulOpenMode, ulAttribute, pFEAList); 1745 1656 } 1746 1657 1747 1658 int APIENTRY NdpOpenReplaceL(HCONNECTION conn, NDFILEINFO *pfi, NDFILEHANDLE *phandle, char *szFileName, LONGLONG llSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList) 1748 1659 { 1749 1660 return smbopen((Connection *)conn, szFileName, O_TRUNC, ulOpenMode, ulAttribute, pFEAList); 1750 1661 } 1751 1662 1752 1663 int APIENTRY NdpOpenCreate (HCONNECTION conn, NDFILEINFOL *pfiparent, NDFILEHANDLE *phandle, char *szFileName, ULONG ulSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList) 1753 1664 { 1754 // return smbopen((Connection *)conn, szFileName, O_CREAT, ulOpenMode, ulAttribute); 1755 return smbopen((Connection *)conn, szFileName, O_CREAT | O_EXCL, ulOpenMode, ulAttribute, pFEAList); 1665 return smbopen((Connection *)conn, szFileName, O_CREAT | O_EXCL, ulOpenMode, ulAttribute, pFEAList); 1756 1666 } 1757 1667 1758 1668 int APIENTRY NdpOpenCreateL(HCONNECTION conn, NDFILEINFO *pfiparent, NDFILEHANDLE *phandle, char *szFileName, LONGLONG llSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList) 1759 1669 { 1760 1670 return smbopen((Connection *)conn, szFileName, O_CREAT | O_EXCL, ulOpenMode, ulAttribute, pFEAList); 1761 1671 } 1762 1672 1763 1673 int APIENTRY NdpOpenExisting (HCONNECTION conn, NDFILEINFOL *pfi, NDFILEHANDLE *phandle, char *szFileName, ULONG ulOpenMode, USHORT *pfNeedEA) 1764 1674 { 1765 if (pfNeedEA) *pfNeedEA = 0; // wtf is this ? 1766 return smbopen((Connection *)conn, szFileName, 0, ulOpenMode, 0, NULL); 1675 if (pfNeedEA) 1676 *pfNeedEA = 0; // wtf is this ? 1677 return smbopen((Connection *)conn, szFileName, 0, ulOpenMode, 0, NULL); 1767 1678 } 1768 1679 1769 1680 int APIENTRY NdpSetFileAttribute (HCONNECTION conn, NDFILEINFOL *pfi, char *szFileName, USHORT usAttr) 1770 1681 { 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 debuglocal(9,"NdpSetFileAttribute in [%p]\n", pConn);1782 1783 1784 if (rc) 1785 { 1786 break; 1787 } 1788 1789 memset(&finfo, 0, sizeof(finfo));1790 strncpy(finfo.fname, path, sizeof(finfo.fname) - 1);1791 finfo.attr = usAttr & 0x37;1792 rc = smbwrp_setattr(pConn->cli, &finfo); 1793 } while (0);1794 debuglocal(9,"NdpSetFileAttribute <%s> (%s) %04x %d\n", szFileName, path, usAttr, rc); 1795 1796 1682 Connection *pConn = (Connection *)conn; 1683 Resource *pRes = pConn->pRes; 1684 int rc = 0; 1685 unsigned long action; 1686 1687 smbwrp_fileinfo finfo; 1688 char path[CCHMAXPATH+1] = {0}; 1689 1690 ENTER(); 1691 1692 debuglocal(9, "NdpSetFileAttribute in [%p]\n", pConn); 1693 do { 1694 rc = pathparser(pRes, pConn, szFileName, path); 1695 if (rc) 1696 break; 1697 1698 memset(&finfo, 0, sizeof(finfo)); 1699 strncpy(finfo.fname, path, sizeof(finfo.fname) - 1); 1700 finfo.attr = usAttr & 0x37; 1701 rc = smbwrp_setattr(pConn->cli, &finfo); 1702 } while (0); 1703 1704 debuglocal(9, "NdpSetFileAttribute <%s> (%s) %04x %d\n", szFileName, path, usAttr, rc); 1705 1706 LEAVE(); 1707 return rc; 1797 1708 } 1798 1709 1799 1710 int APIENTRY NdpFlush (HRESOURCE resource) 1800 1711 { 1801 debuglocal(9,"NdpFlush %d\n", ERROR_NOT_SUPPORTED); 1802 return ERROR_NOT_SUPPORTED; 1803 } 1804 1805 // Called when a new thread will call the plugin. Allows to do per thread init, like disable signals. 1712 debuglocal(9, "NdpFlush %d\n", ERROR_NOT_SUPPORTED); 1713 return ERROR_NOT_SUPPORTED; 1714 } 1715 1716 /* 1717 * Called when a new thread will call the plugin. 1718 * Allows to do per thread init, like disable signals. 1719 */ 1806 1720 #define ND_PL_INIT_THREAD 0xFFFF0000 1807 1721 1808 1722 int APIENTRY NdpIOCTL (int type, HRESOURCE resource, char *path, int function, void *in, ULONG insize, PULONG poutlen) 1809 1723 { 1810 1811 1812 1813 1814 1815 1816 1817 debuglocal(9,"NdpIOCTL <%s> %d\n", path, function);1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1724 if (function == ND_PL_INIT_THREAD) 1725 { 1726 smbwrp_initthread(); 1727 debuglocal(9, "NdpIOCTL init thread\n"); 1728 return NO_ERROR; 1729 } 1730 1731 debuglocal(9, "NdpIOCTL <%s> %d\n", path, function); 1732 1733 if (in && insize > 4096) 1734 { 1735 char out[4096]; 1736 sprintf (out, "SAMBA IOCTL function = %d, parms [%s] insize = %d, *poutlen = %d", function, in, insize, *poutlen); 1737 *poutlen = strlen(out); 1738 strcpy (in, out); 1739 return NO_ERROR; 1740 } 1741 1742 return ERROR_NOT_SUPPORTED; 1829 1743 } 1830 1744 1831 1745 int APIENTRY NdpFileQueryInfo (HCONNECTION conn, NDFILEHANDLE handle, void *plist) 1832 1746 { 1833 Connection *pConn = (Connection *)conn; 1834 Resource *pRes = pConn->pRes; 1835 int rc = 0; 1836 unsigned long action; 1837 smbwrp_fileinfo finfo; 1838 1839 ENTER(); 1840 1841 debug_printf("NdpFileQueryInfo in [%p]\n", pConn); 1842 do { 1843 if (pConn->file.fd < 0 || !*pConn->file.fname) 1844 { 1845 rc = ERROR_INVALID_HANDLE; 1846 break; 1847 } 1848 strncpy(finfo.fname, pConn->file.fname, sizeof(finfo.fname) - 1); 1849 rc = smbwrp_fgetattr(pConn->cli, &pConn->file, &finfo); 1850 if (!rc) 1851 { 1852 finfo.easize = -1; 1853 getfindinfoL(pConn, plist, &finfo, 0, NULL); 1854 } 1855 } while (0); 1856 debuglocal(9,"NdpFileQueryInfo <%s> %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, rc); 1857 LEAVE(); 1858 return rc; 1747 Connection *pConn = (Connection *)conn; 1748 Resource *pRes = pConn->pRes; 1749 int rc = 0; 1750 unsigned long action; 1751 smbwrp_fileinfo finfo; 1752 1753 ENTER(); 1754 1755 debuglocal(9, "NdpFileQueryInfo in [%p]\n", pConn); 1756 do { 1757 if (pConn->file.fd < 0 || !*pConn->file.fname) 1758 { 1759 rc = ERROR_INVALID_HANDLE; 1760 break; 1761 } 1762 strncpy(finfo.fname, pConn->file.fname, sizeof(finfo.fname) - 1); 1763 rc = smbwrp_fgetattr(pConn->cli, &pConn->file, &finfo); 1764 if (!rc) 1765 { 1766 finfo.easize = -1; 1767 getfindinfoL(pConn, plist, &finfo, 0, NULL); 1768 } 1769 } while (0); 1770 1771 debuglocal(9, "NdpFileQueryInfo <%s> %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, rc); 1772 1773 LEAVE(); 1774 return rc; 1859 1775 } 1860 1776 1861 1777 int APIENTRY NdpFileEAQuery (HCONNECTION conn, NDFILEHANDLE handle, GEALIST *pGEAList, FEALIST *pFEAList) 1862 1778 { 1863 Connection *pConn = (Connection *)conn; 1864 Resource *pRes = pConn->pRes; 1865 int rc = 0; 1866 unsigned long action; 1867 const int cbBuffer = 64*1024; 1868 FEALIST * pFEASrc; 1869 1870 if (!pFEAList) 1871 { 1872 return ERROR_EAS_NOT_SUPPORTED; 1873 } 1874 if (!pRes->easupport) 1875 { 1876 return ERROR_EAS_NOT_SUPPORTED; 1877 } 1878 1879 debuglocal(9,"NdpFileEAQuery in [%p] <%s>/%d pGEAList=%08x\n", pConn, pConn->file.fname, pConn->file.fd, pGEAList); 1880 1881 char *pchBuffer = (char *)malloc(cbBuffer); 1882 if (!pchBuffer) 1883 return ERROR_NOT_ENOUGH_MEMORY; 1884 1885 ENTER(); 1886 1887 do { 1888 if (pConn->file.fd < 0) 1889 { 1890 rc = ERROR_INVALID_HANDLE; 1891 break; 1892 } 1893 rc = smbwrp_flistea(pConn->cli, &pConn->file, pchBuffer, cbBuffer); 1894 pFEASrc = (FEALIST *)pchBuffer; 1895 if (rc) 1896 { 1897 //rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER); 1898 switch (rc) 1899 { 1900 case ERROR_FILE_NOT_FOUND : 1901 case ERROR_PATH_NOT_FOUND : 1902 { 1903 pFEAList->cbList = sizeof(pFEAList->cbList); 1904 rc = NO_ERROR; 1905 } break; 1906 case ERROR_BUFFER_OVERFLOW : 1907 { 1908 pFEAList->cbList = pFEASrc->cbList; 1909 } break; 1910 default : 1911 { 1912 rc = ERROR_EAS_NOT_SUPPORTED; 1913 } 1914 } 1915 } 1916 else 1917 { 1918 rc = buildFEALIST(pFEASrc, pGEAList, pFEAList); 1919 } 1920 } while (0); 1921 free(pchBuffer); 1922 debuglocal(9,"NdpFileEAQuery out <%s>/%d pFEASrc->cbList=%d pFEAList->cbList=%d rc=%d\n", pConn->file.fname, pConn->file.fd, pFEASrc->cbList, pFEAList->cbList, rc); 1923 LEAVE(); 1924 return rc; 1779 Connection *pConn = (Connection *)conn; 1780 Resource *pRes = pConn->pRes; 1781 int rc = 0; 1782 unsigned long action; 1783 const int cbBuffer = 64*1024; 1784 FEALIST * pFEASrc; 1785 1786 if (!pFEAList) 1787 return ERROR_EAS_NOT_SUPPORTED; 1788 if (!pRes->easupport) 1789 return ERROR_EAS_NOT_SUPPORTED; 1790 1791 debuglocal(9, "NdpFileEAQuery in [%p] <%s>/%d pGEAList=%08x\n", pConn, pConn->file.fname, pConn->file.fd, pGEAList); 1792 1793 char *pchBuffer = (char *)malloc(cbBuffer); 1794 if (!pchBuffer) 1795 return ERROR_NOT_ENOUGH_MEMORY; 1796 1797 ENTER(); 1798 1799 do { 1800 if (pConn->file.fd < 0) 1801 { 1802 rc = ERROR_INVALID_HANDLE; 1803 break; 1804 } 1805 rc = smbwrp_flistea(pConn->cli, &pConn->file, pchBuffer, cbBuffer); 1806 pFEASrc = (FEALIST *)pchBuffer; 1807 if (rc) 1808 { 1809 switch (rc) 1810 { 1811 case ERROR_FILE_NOT_FOUND : 1812 case ERROR_PATH_NOT_FOUND : 1813 pFEAList->cbList = sizeof(pFEAList->cbList); 1814 rc = NO_ERROR; 1815 break; 1816 case ERROR_BUFFER_OVERFLOW : 1817 pFEAList->cbList = pFEASrc->cbList; 1818 break; 1819 default : 1820 rc = ERROR_EAS_NOT_SUPPORTED; 1821 } 1822 } 1823 else 1824 rc = buildFEALIST(pFEASrc, pGEAList, pFEAList); 1825 1826 } while (0); 1827 1828 free(pchBuffer); 1829 debuglocal(9, "NdpFileEAQuery out <%s>/%d pFEASrc->cbList=%d pFEAList->cbList=%d rc=%d\n", pConn->file.fname, pConn->file.fd, pFEASrc->cbList, pFEAList->cbList, rc); 1830 1831 LEAVE(); 1832 return rc; 1925 1833 } 1926 1834 1927 1835 int APIENTRY NdpFileEASet (HCONNECTION conn, NDFILEHANDLE handle, FEALIST *pFEAList) 1928 1836 { 1929 Connection *pConn = (Connection *)conn; 1930 Resource *pRes = pConn->pRes; 1931 int rc = 0; 1932 unsigned long action; 1933 1934 debuglocal(9,"NdpFileEASet in [%p]\n", pConn); 1935 1936 if (!pFEAList || pFEAList->cbList <= sizeof(long)) 1937 { 1938 return ERROR_EAS_NOT_SUPPORTED; 1939 } 1940 if (!pRes->easupport) 1941 { 1942 return ERROR_EAS_NOT_SUPPORTED; 1943 } 1944 1945 ENTER(); 1946 1947 do { 1948 // got FEA there 1949 FEA * pfea; 1950 unsigned long done = sizeof(long); 1951 if (pConn->file.fd < 0) 1952 { 1953 rc = ERROR_INVALID_HANDLE; 1954 break; 1955 } 1956 1957 pfea = pFEAList->list; 1958 while (done < pFEAList->cbList) 1959 { 1960 rc = smbwrp_fsetea(pConn->cli, &pConn->file, (char *)(pfea + 1), pfea->cbValue ? (char *)(pfea + 1) + pfea->cbName + 1: NULL, pfea->cbValue); 1961 if (rc) 1962 { 1963 break; 1964 } 1965 pfea = (FEA *)((char *)(pfea + 1) + pfea->cbName + 1 + pfea->cbValue); 1966 done += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue; 1967 } 1968 1969 } while (0); 1970 debuglocal(9,"NdpFileEASet %d\n", rc); 1971 LEAVE(); 1972 return rc; 1837 Connection *pConn = (Connection *)conn; 1838 Resource *pRes = pConn->pRes; 1839 int rc = 0; 1840 unsigned long action; 1841 1842 debuglocal(9, "NdpFileEASet in [%p]\n", pConn); 1843 1844 if (!pFEAList || pFEAList->cbList <= sizeof(long)) 1845 return ERROR_EAS_NOT_SUPPORTED; 1846 1847 if (!pRes->easupport) 1848 return ERROR_EAS_NOT_SUPPORTED; 1849 1850 ENTER(); 1851 1852 do { 1853 // got FEA there 1854 FEA * pfea; 1855 unsigned long done = sizeof(long); 1856 if (pConn->file.fd < 0) 1857 { 1858 rc = ERROR_INVALID_HANDLE; 1859 break; 1860 } 1861 1862 pfea = pFEAList->list; 1863 while (done < pFEAList->cbList) 1864 { 1865 rc = smbwrp_fsetea(pConn->cli, &pConn->file, (char *)(pfea + 1), pfea->cbValue ? (char *)(pfea + 1) + pfea->cbName + 1: NULL, pfea->cbValue); 1866 if (rc) 1867 break; 1868 1869 pfea = (FEA *)((char *)(pfea + 1) + pfea->cbName + 1 + pfea->cbValue); 1870 done += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue; 1871 } 1872 1873 } while (0); 1874 1875 debuglocal(9, "NdpFileEASet %d\n", rc); 1876 1877 LEAVE(); 1878 return rc; 1973 1879 } 1974 1880 1975 1881 int APIENTRY NdpFileEASize (HCONNECTION conn, NDFILEHANDLE handle, ULONG *pulEASize) 1976 1882 { 1977 Connection *pConn = (Connection *)conn; 1978 Resource *pRes = pConn->pRes; 1979 int rc = 0; 1980 unsigned long action; 1981 char path[CCHMAXPATH+1] = {0}; 1982 FEALIST * pFEAList; 1983 const int cbBuffer = 64*1024; 1984 1985 if (!pulEASize) 1986 { 1987 return ERROR_EAS_NOT_SUPPORTED; 1988 } 1989 if (!pRes->easupport) 1990 { 1991 return ERROR_EAS_NOT_SUPPORTED; 1992 } 1993 1994 debuglocal(9,"NdpFileEASize in [%p] <%s>/%d \n", pConn, pConn->file.fname, pConn->file.fd); 1995 1996 char *pchBuffer = (char *)malloc(cbBuffer); 1997 if (!pchBuffer) 1998 return ERROR_NOT_ENOUGH_MEMORY; 1999 2000 ENTER(); 2001 2002 do { 2003 if (pConn->file.fd < 0) 2004 { 2005 rc = ERROR_INVALID_HANDLE; 2006 break; 2007 } 2008 rc = smbwrp_flistea(pConn->cli, &pConn->file, pchBuffer, cbBuffer); 2009 pFEAList = (FEALIST*)pchBuffer; 2010 if (rc) 2011 { 2012 //rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER); 2013 switch (rc) 2014 { 2015 case ERROR_FILE_NOT_FOUND : 2016 case ERROR_PATH_NOT_FOUND : 2017 { 2018 pFEAList->cbList = sizeof(pFEAList->cbList); 2019 } /* Fall through */ 2020 case ERROR_BUFFER_OVERFLOW : 2021 { 2022 rc = NO_ERROR; 2023 } break; 2024 default : 2025 { 2026 rc = ERROR_EAS_NOT_SUPPORTED; 2027 } 2028 } 2029 } 2030 *pulEASize = pFEAList->cbList; 2031 } while (0); 2032 free(pchBuffer); 2033 debuglocal(9,"NdpFileEASize %d %d\n", *pulEASize, rc); 2034 LEAVE(); 2035 return rc; 1883 Connection *pConn = (Connection *)conn; 1884 Resource *pRes = pConn->pRes; 1885 int rc = 0; 1886 unsigned long action; 1887 char path[CCHMAXPATH+1] = {0}; 1888 FEALIST * pFEAList; 1889 const int cbBuffer = 64*1024; 1890 1891 if (!pulEASize) 1892 return ERROR_EAS_NOT_SUPPORTED; 1893 1894 if (!pRes->easupport) 1895 return ERROR_EAS_NOT_SUPPORTED; 1896 1897 debuglocal(9, "NdpFileEASize in [%p] <%s>/%d \n", pConn, pConn->file.fname, pConn->file.fd); 1898 1899 char *pchBuffer = (char *)malloc(cbBuffer); 1900 if (!pchBuffer) 1901 return ERROR_NOT_ENOUGH_MEMORY; 1902 1903 ENTER(); 1904 1905 do { 1906 if (pConn->file.fd < 0) 1907 { 1908 rc = ERROR_INVALID_HANDLE; 1909 break; 1910 } 1911 rc = smbwrp_flistea(pConn->cli, &pConn->file, pchBuffer, cbBuffer); 1912 pFEAList = (FEALIST*)pchBuffer; 1913 if (rc) 1914 { 1915 switch (rc) 1916 { 1917 case ERROR_FILE_NOT_FOUND : 1918 case ERROR_PATH_NOT_FOUND : 1919 pFEAList->cbList = sizeof(pFEAList->cbList);// Fall through */ 1920 case ERROR_BUFFER_OVERFLOW : 1921 rc = NO_ERROR; 1922 break; 1923 default : 1924 rc = ERROR_EAS_NOT_SUPPORTED; 1925 } 1926 } 1927 *pulEASize = pFEAList->cbList; 1928 } while (0); 1929 1930 free(pchBuffer); 1931 debuglocal(9, "NdpFileEASize %d %d\n", *pulEASize, rc); 1932 1933 LEAVE(); 1934 return rc; 2036 1935 } 2037 1936 2038 1937 int APIENTRY NdpFileSetInfo (HCONNECTION conn, NDFILEHANDLE handle, NDFILEINFOL *pfi) 2039 1938 { 2040 Connection *pConn = (Connection *)conn; 2041 Resource *pRes = pConn->pRes; 2042 int rc = 0; 2043 unsigned long action, attrFile; 2044 2045 ENTER(); 2046 2047 debug_printf("NdpFileSetInfo in [%p]\n", pConn); 2048 2049 // delete the dir cache 2050 dircache_invalidate(pConn->file.fullname, pRes->pdc, 1); 2051 2052 do { 2053 if (pConn->file.fd < 0 || !*pConn->file.fname) 2054 { 2055 rc = ERROR_INVALID_HANDLE; 2056 break; 2057 } 2058 attrFile = pfi->stat.attrFile; 2059 // deferred setinfo - on closing the file 2060 pConn->file.openattr = attrFile; 2061 fsphDosDateToUnixTime(pfi->stat.fdateLastWrite, pfi->stat.ftimeLastWrite, &(pConn->file.mtime)); 2062 fsphDosDateToUnixTime(pfi->stat.fdateCreation, pfi->stat.ftimeCreation, &(pConn->file.ctime)); 2063 pConn->file.updatetime = 2; 2064 debug_printf("NdpFileSetInfo mtime %d\n", pConn->file.mtime); 2065 } while (0); 2066 debuglocal(9,"NdpFileSetInfo <%s> %08x %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, attrFile, rc); 2067 LEAVE(); 2068 return NO_ERROR; 1939 Connection *pConn = (Connection *)conn; 1940 Resource *pRes = pConn->pRes; 1941 int rc = 0; 1942 unsigned long action, attrFile; 1943 1944 ENTER(); 1945 1946 debuglocal(9, "NdpFileSetInfo in [%p]\n", pConn); 1947 1948 // delete the dir cache 1949 dircache_invalidate(pConn->file.fullname, pRes->pdc, 1); 1950 1951 do { 1952 if (pConn->file.fd < 0 || !*pConn->file.fname) 1953 { 1954 rc = ERROR_INVALID_HANDLE; 1955 break; 1956 } 1957 attrFile = pfi->stat.attrFile; 1958 // deferred setinfo - on closing the file 1959 pConn->file.openattr = attrFile; 1960 fsphDosDateToUnixTime(pfi->stat.fdateLastWrite, pfi->stat.ftimeLastWrite, &(pConn->file.mtime)); 1961 fsphDosDateToUnixTime(pfi->stat.fdateCreation, pfi->stat.ftimeCreation, &(pConn->file.ctime)); 1962 pConn->file.updatetime = 2; 1963 debuglocal(9, "NdpFileSetInfo mtime %d\n", pConn->file.mtime); 1964 } while (0); 1965 1966 debuglocal(9, "NdpFileSetInfo <%s> %08x %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, attrFile, rc); 1967 1968 LEAVE(); 1969 return NO_ERROR; 2069 1970 } 2070 1971 2071 1972 int APIENTRY NdpFileSetFilePtrL(HCONNECTION conn, NDFILEHANDLE handle, LONGLONG llOffset, ULONG ulMethod, LONGLONG *pllActual) 2072 1973 { 2073 Connection *pConn = (Connection *)conn; 2074 Resource *pRes = pConn->pRes; 2075 int rc = 0; 2076 unsigned long action; 2077 2078 ENTER(); 2079 2080 debuglocal(9,"NdpFileSetFilePtrL in [%p]\n", pConn); 2081 2082 do { 2083 if (pConn->file.fd < 0) 2084 { 2085 rc = ERROR_INVALID_HANDLE; 2086 break; 2087 } 2088 2089 rc = smbwrp_lseek(pConn->cli, &pConn->file, ulMethod, llOffset); 2090 if (!rc) 2091 *pllActual = pConn->file.offset; 2092 2093 } while (0); 2094 debuglocal(9,"NdpFileSetFilePtrL <%s> %lld %lu %lld %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, llOffset, ulMethod, *pllActual, rc); 2095 LEAVE(); 2096 return rc; 1974 Connection *pConn = (Connection *)conn; 1975 Resource *pRes = pConn->pRes; 1976 int rc = 0; 1977 unsigned long action; 1978 1979 ENTER(); 1980 1981 debuglocal(9, "NdpFileSetFilePtrL in [%p]\n", pConn); 1982 1983 do { 1984 if (pConn->file.fd < 0) 1985 { 1986 rc = ERROR_INVALID_HANDLE; 1987 break; 1988 } 1989 1990 rc = smbwrp_lseek(pConn->cli, &pConn->file, ulMethod, llOffset); 1991 if (!rc) 1992 *pllActual = pConn->file.offset; 1993 1994 } while (0); 1995 1996 debuglocal(9, "NdpFileSetFilePtrL <%s> %lld %lu %lld %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, llOffset, ulMethod, *pllActual, rc); 1997 1998 LEAVE(); 1999 return rc; 2097 2000 } 2098 2001 2099 2002 int APIENTRY NdpFileSetFilePtr (HCONNECTION conn, NDFILEHANDLE handle, LONG lOffset, ULONG ulMethod, ULONG *pulActual) 2100 2003 { 2101 2102 2103 2104 debuglocal(9,"NdpFileSetFilePtr %ld %lu %ld %d\n", lOffset, ulMethod, *pulActual, rc);2105 2004 LONGLONG llActual; 2005 int rc = NdpFileSetFilePtrL(conn, handle, lOffset, ulMethod, &llActual); 2006 *pulActual = llActual & 0xFFFFFFFF; 2007 debuglocal(9, "NdpFileSetFilePtr %ld %lu %ld %d\n", lOffset, ulMethod, *pulActual, rc); 2008 return rc; 2106 2009 } 2107 2010 2108 2011 int APIENTRY NdpFileClose (HCONNECTION conn, NDFILEHANDLE handle) 2109 2012 { 2110 Connection *pConn = (Connection *)conn; 2111 Resource *pRes = pConn->pRes; 2112 int rc = 0; 2113 unsigned long action; 2114 2115 ENTER(); 2116 2117 debuglocal(9,"NdpFileClose in [%p] %d <%s>\n", pConn, pConn->file.fd, pConn->file.fd < 0 ? "!null!" : pConn->file.fname); 2118 2119 do { 2120 if (pConn->file.fd < 0) 2121 { 2122 rc = ERROR_INVALID_HANDLE; 2123 break; 2124 } 2125 2126 rc = smbwrp_close(pConn->cli, &pConn->file); 2127 2128 } while (0); 2129 debuglocal(9,"NdpFileClose %d %d\n", pConn->file.fd, rc); 2130 2131 pConn->file.fd = -1; 2132 LEAVE(); 2133 return rc; 2013 Connection *pConn = (Connection *)conn; 2014 Resource *pRes = pConn->pRes; 2015 int rc = 0; 2016 unsigned long action; 2017 2018 ENTER(); 2019 2020 debuglocal(9, "NdpFileClose in [%p] %d <%s>\n", pConn, pConn->file.fd, pConn->file.fd < 0 ? "!null!" : pConn->file.fname); 2021 2022 do { 2023 if (pConn->file.fd < 0) 2024 { 2025 rc = ERROR_INVALID_HANDLE; 2026 break; 2027 } 2028 2029 rc = smbwrp_close(pConn->cli, &pConn->file); 2030 2031 } while (0); 2032 2033 debuglocal(9, "NdpFileClose %d %d\n", pConn->file.fd, rc); 2034 pConn->file.fd = -1; 2035 2036 LEAVE(); 2037 return rc; 2134 2038 } 2135 2039 2136 2040 int APIENTRY NdpFileCommit (HCONNECTION conn, NDFILEHANDLE handle) 2137 2041 { 2138 debuglocal(9,"NdpFileCommit %d\n", NO_ERROR); 2139 return NO_ERROR; 2140 } 2141 2042 debuglocal(9, "NdpFileCommit %d\n", NO_ERROR); 2043 return NO_ERROR; 2044 } 2142 2045 2143 2046 int APIENTRY NdpFileNewSize (HCONNECTION conn, NDFILEHANDLE handle, ULONG ulLen) 2144 2047 { 2145 2146 debuglocal(9,"NdpFileNewSize %ld %d\n", ulLen, rc);2147 2048 int rc = NdpFileNewSizeL(conn, handle, ulLen); 2049 debuglocal(9, "NdpFileNewSize %ld %d\n", ulLen, rc); 2050 return rc; 2148 2051 } 2149 2052 2150 2053 int APIENTRY NdpFileNewSizeL(HCONNECTION conn, NDFILEHANDLE handle, LONGLONG llLen) 2151 2054 { 2152 Connection *pConn = (Connection *)conn; 2153 Resource *pRes = pConn->pRes; 2154 int rc = 0; 2155 unsigned long action; 2156 2157 ENTER(); 2158 2159 debuglocal(9,"NdpFileNewSizeL in [%p]\n", pConn); 2160 2161 do { 2162 if (pConn->file.fd < 0) 2163 { 2164 rc = ERROR_INVALID_HANDLE; 2165 break; 2166 } 2167 2168 rc = smbwrp_setfilesize(pConn->cli, &pConn->file, llLen); 2169 2170 } while (0); 2171 debuglocal(9,"NdpFileNewSizeL <%s> %lld %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, llLen, rc); 2172 LEAVE(); 2173 return rc; 2055 Connection *pConn = (Connection *)conn; 2056 Resource *pRes = pConn->pRes; 2057 int rc = 0; 2058 unsigned long action; 2059 2060 ENTER(); 2061 2062 debuglocal(9, "NdpFileNewSizeL in [%p]\n", pConn); 2063 2064 do { 2065 if (pConn->file.fd < 0) 2066 { 2067 rc = ERROR_INVALID_HANDLE; 2068 break; 2069 } 2070 2071 rc = smbwrp_setfilesize(pConn->cli, &pConn->file, llLen); 2072 2073 } while (0); 2074 2075 debuglocal(9, "NdpFileNewSizeL <%s> %lld %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, llLen, rc); 2076 2077 LEAVE(); 2078 return rc; 2174 2079 } 2175 2080 … … 2178 2083 int APIENTRY NdpFileRead (HCONNECTION conn, NDFILEHANDLE handle, void *pBuffer, ULONG ulRead, ULONG *pulActual) 2179 2084 { 2180 Connection *pConn = (Connection *)conn; 2181 Resource *pRes = pConn->pRes; 2182 int rc = 0; 2183 unsigned long done = 0; 2184 unsigned long onedone; 2185 unsigned long action; 2186 ULONG ulReadCompleted = 0; 2187 2188 ENTER(); 2189 2190 debuglocal(9,"NdpFileRead in [%p]\n", pConn); 2191 2192 do { 2193 if (pConn->file.fd < 0) 2194 { 2195 rc = ERROR_INVALID_HANDLE; 2196 break; 2197 } 2198 while (ulReadCompleted < ulRead) 2199 { 2200 ULONG ulActual; 2201 ULONG ulToRead = ulRead - ulReadCompleted; 2202 debuglocal(9,"NdpFileRead completed %d, to read %d\n", ulReadCompleted, ulToRead); 2203 if (ulToRead > NDPSMB_READ_MAX_SIZE) 2204 { 2205 ulToRead = NDPSMB_READ_MAX_SIZE; 2206 } 2207 rc = smbwrp_read(pConn->cli, &pConn->file, (char *)pBuffer + ulReadCompleted, ulToRead, &ulActual); 2208 if (ulActual == 0 || rc != NO_ERROR) 2209 { 2210 break; 2211 } 2212 ulReadCompleted += ulActual; 2213 } 2214 //*pulActual = ulRead; 2215 //DosSleep(0); 2216 2217 } while (0); 2218 2219 if (ulReadCompleted > 0) 2220 { 2221 rc = NO_ERROR; /* Still were able to read some data. */ 2222 } 2223 2224 if (rc == NO_ERROR) 2225 { 2226 *pulActual = ulReadCompleted; 2227 } 2228 2229 debuglocal(9,"NdpFileRead <%s> %lu %lu %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, ulRead, *pulActual, rc); 2230 LEAVE(); 2231 return rc; 2085 Connection *pConn = (Connection *)conn; 2086 Resource *pRes = pConn->pRes; 2087 int rc = 0; 2088 unsigned long done = 0; 2089 unsigned long onedone; 2090 unsigned long action; 2091 ULONG ulReadCompleted = 0; 2092 2093 ENTER(); 2094 2095 debuglocal(9, "NdpFileRead in [%p]\n", pConn); 2096 2097 do { 2098 if (pConn->file.fd < 0) 2099 { 2100 rc = ERROR_INVALID_HANDLE; 2101 break; 2102 } 2103 2104 while (ulReadCompleted < ulRead) 2105 { 2106 ULONG ulActual; 2107 ULONG ulToRead = ulRead - ulReadCompleted; 2108 debuglocal(9, "NdpFileRead completed %d, to read %d\n", ulReadCompleted, ulToRead); 2109 2110 if (ulToRead > NDPSMB_READ_MAX_SIZE) 2111 ulToRead = NDPSMB_READ_MAX_SIZE; 2112 2113 rc = smbwrp_read(pConn->cli, &pConn->file, (char *)pBuffer + ulReadCompleted, ulToRead, &ulActual); 2114 if (ulActual == 0 || rc != NO_ERROR) 2115 break; 2116 2117 ulReadCompleted += ulActual; 2118 } 2119 } while (0); 2120 2121 if (ulReadCompleted > 0) 2122 rc = NO_ERROR; // Still were able to read some data. 2123 2124 if (rc == NO_ERROR) 2125 *pulActual = ulReadCompleted; 2126 2127 debuglocal(9, "NdpFileRead <%s> %lu %lu %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, ulRead, *pulActual, rc); 2128 2129 LEAVE(); 2130 return rc; 2232 2131 } 2233 2132 2234 2133 int APIENTRY NdpFileWrite (HCONNECTION conn, NDFILEHANDLE handle, void *pBuffer, ULONG ulWrite, ULONG *pulActual) 2235 2134 { 2236 Connection *pConn = (Connection *)conn; 2237 Resource *pRes = pConn->pRes; 2238 int rc = 0; 2239 unsigned long done = 0; 2240 unsigned long onedone; 2241 unsigned long action; 2242 2243 ENTER(); 2244 2245 debuglocal(9,"NdpFileWrite in [%p]\n", pConn); 2246 2247 /* delete the dir cache 2248 this was moved from NdpFileClose() becasue if there are a lot files in the tree all are reread 2249 the problem when moved to here is, that last accessed time is not refreshed 2250 if this is needed, a new function needs to be done to update only one file in the cache */ 2251 dircache_invalidate(pConn->file.fullname, pRes->pdc, 1); 2252 2253 do { 2254 if (pConn->file.fd < 0) 2255 { 2256 rc = ERROR_INVALID_HANDLE; 2257 break; 2258 } 2259 rc = smbwrp_write(pConn->cli, &pConn->file, pBuffer, ulWrite, pulActual); 2260 2261 } while (0); 2262 debuglocal(9,"NdpFileWrite <%s> %lu %lu %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, ulWrite, *pulActual, rc); 2263 LEAVE(); 2264 return rc; 2265 } 2266 2135 Connection *pConn = (Connection *)conn; 2136 Resource *pRes = pConn->pRes; 2137 int rc = 0; 2138 unsigned long done = 0; 2139 unsigned long onedone; 2140 unsigned long action; 2141 2142 ENTER(); 2143 2144 debuglocal(9, "NdpFileWrite in [%p]\n", pConn); 2145 2146 /* 2147 * delete the dir cache 2148 * This was moved from NdpFileClose() becasue if there are a lot files 2149 * in the tree, all are reread. The problem when moved to here is, that 2150 * the last accessed time is not refreshed. If this is needed, 2151 * a new function needs to be done to update only one file in the cache 2152 */ 2153 dircache_invalidate(pConn->file.fullname, pRes->pdc, 1); 2154 2155 do { 2156 if (pConn->file.fd < 0) 2157 { 2158 rc = ERROR_INVALID_HANDLE; 2159 break; 2160 } 2161 rc = smbwrp_write(pConn->cli, &pConn->file, pBuffer, ulWrite, pulActual); 2162 2163 } while (0); 2164 2165 debuglocal(9, "NdpFileWrite <%s> %lu %lu %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, ulWrite, *pulActual, rc); 2166 2167 LEAVE(); 2168 return rc; 2169 }
Note:
See TracChangeset
for help on using the changeset viewer.