Changeset 959
- Timestamp:
- Aug 16, 2016, 5:35:07 PM (9 years ago)
- Location:
- trunk/client/src
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/client/src/debug.c
r957 r959 43 43 int debuglvl(int level) 44 44 { 45 45 return (level <= debuglevel) ? 1 : 0; 46 46 } 47 47 … … 79 79 } 80 80 else 81 {82 81 strncat(logfile, logfilename, sizeof(logfile) -1); 83 }82 84 83 // set the samba logging stuff 85 84 do_logging = TRUE; … … 88 87 rc = DosCreateMutexSem(nameMutex, &logMutex, 0, FALSE); 89 88 if (rc == ERROR_DUPLICATE_NAME) 90 { 91 rc = DosOpenMutexSem(nameMutex, &logMutex); 92 } 89 rc = DosOpenMutexSem(nameMutex, &logMutex); 93 90 94 91 return; … … 107 104 // do we have to log at all 108 105 if (!do_logging) 109 { 110 return; 111 } 106 return; 112 107 113 108 // if the sem is created we request it 114 109 if (logMutex) 115 {116 110 DosRequestMutexSem(logMutex, (ULONG) SEM_INDEFINITE_WAIT); 117 }118 111 119 do 120 { 121 struct timeval tv; 122 char buf[80] = {0}; 123 va_list args; 124 if (logfile[0]) 125 { 126 f = fopen(logfile, "a"); 127 if (!f) 128 { 129 break; 130 } 131 } 132 else 133 { 134 f = stdout; 135 } 112 do { 113 struct timeval tv; 114 char buf[80] = {0}; 115 va_list args; 116 if (logfile[0]) 117 { 118 f = fopen(logfile, "a"); 119 if (!f) 120 break; 121 } 122 else 123 f = stdout; 136 124 137 138 139 140 141 142 143 125 // in the first log line we write our version of the client 126 if (firstLogLine) 127 { 128 fprintf(f, "Samba client %s build %s based on %s\n", VERSION, BUILD, smbwrp_getVersion()); 129 fprintf(f, "This build is maintained by %s\n", VENDOR); 130 firstLogLine = FALSE; 131 } 144 132 145 gettimeofday(&tv, NULL); 146 strftime(buf,sizeof(buf)-1,"%Y/%m/%d %H:%M:%S", localtime((time_t *)&tv.tv_sec)); 147 fprintf(f, "%s.%d: %d %d: ", buf, tv.tv_usec / 10000, level, (long)_gettid()); 148 va_start(args, fmt); 149 vfprintf(f, fmt, args); 150 va_end(args); 151 if (logfile) 152 { 153 // fflush(f); 154 fclose(f); 155 } 156 } 157 while (0); 133 gettimeofday(&tv, NULL); 134 strftime(buf,sizeof(buf)-1,"%Y/%m/%d %H:%M:%S", localtime((time_t *)&tv.tv_sec)); 135 fprintf(f, "%s.%d: %d %d: ", buf, tv.tv_usec / 10000, level, (long)_gettid()); 136 va_start(args, fmt); 137 vfprintf(f, fmt, args); 138 va_end(args); 139 if (logfile) 140 fclose(f); 141 142 } while (0); 158 143 159 144 // if the sem is created we release it 160 145 if (logMutex) 161 {162 146 DosReleaseMutexSem(logMutex); 163 }164 147 165 148 return; -
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 } -
trunk/client/src/smbwrp.c
r957 r959 34 34 int os2cli_errno(cli_state * cli) 35 35 { 36 if (cli->fd == -1) 37 { 38 return maperror( ENOTCONN); 39 } 40 return maperror(cli_errno(cli)); 36 if (cli->fd == -1) 37 return maperror(ENOTCONN); 38 39 return maperror(cli_errno(cli)); 41 40 } 42 41 43 42 void smbwrp_Logging() 44 43 { 45 46 47 48 49 50 51 52 53 54 55 { 56 strncpy(slogfile, slogfilename, sizeof(slogfile) -1); 57 } 58 59 // init samba for debug messages 60 setup_logging("ndpsmb", DEBUG_FILE);61 lp_set_logfile(slogfile);62 lp_set_cmdline("log level", "10"); 63 reopen_logs();64 65 } 44 char slogfile[_MAX_PATH +1] = {0}; 45 char slogfilename[] = "log.smbc"; 46 char *env = getenv("LOGFILES"); 47 if (env != NULL) 48 { 49 strncpy(slogfile, env, sizeof(slogfile) -1); 50 strncat(slogfile, "\\", sizeof(slogfile) - strlen(slogfile) -1); 51 strncat(slogfile, slogfilename, sizeof(slogfile) - strlen(slogfile) -1); 52 } 53 else 54 strncpy(slogfile, slogfilename, sizeof(slogfile) -1); 55 56 // init samba for debug messages 57 setup_logging("ndpsmb", DEBUG_FILE); 58 lp_set_logfile(slogfile); 59 lp_set_cmdline("log level", "10"); 60 reopen_logs(); 61 62 return; 63 } 64 66 65 const char * smbwrp_getVersion() 67 66 { 68 67 return samba_version_string(); 69 68 } 70 69 71 70 int _System smbwrp_getclisize(void) 72 71 { 73 74 } 75 76 /* ****************************************************77 initialise structures78 *******************************************************/72 return sizeof(struct cli_state); 73 } 74 75 /* 76 * initialise structures 77 */ 79 78 int _System smbwrp_init(void) 80 79 { 81 static int initialised = 0; 82 char *p; 83 84 if (initialised) 85 { 86 return 0; 87 } 88 initialised = 1; 89 90 lp_set_in_client(true); /* Make sure that we tell lp_load we are client */ 91 92 load_case_tables(); 93 94 if (!lp_load(get_dyn_CONFIGFILE(),true,false,false,true)) { 95 debuglocal(0,("The initial smb.conf is missing, defaults are used!\n")); 96 } 97 98 load_interfaces(); 99 100 if (!init_names()) 101 { 102 return 1; 103 } 104 105 if (writeLog()) 106 { 107 smbwrp_Logging(); 108 } 109 110 /* 111 if ((p=smbw_getshared("RESOLVE_ORDER"))) { 112 lp_set_name_resolve_order(p); 113 } 114 */ 115 return 0; 80 static int initialised = 0; 81 char *p; 82 83 if (initialised) 84 return 0; 85 86 initialised = 1; 87 88 lp_set_in_client(true); // Make sure that we tell lp_load we are client 89 90 load_case_tables(); 91 92 if (!lp_load(get_dyn_CONFIGFILE(),true,false,false,true)) 93 debuglocal(0,("The initial smb.conf is missing, defaults are used!\n")); 94 95 load_interfaces(); 96 97 if (!init_names()) 98 return 1; 99 100 if (writeLog()) 101 smbwrp_Logging(); 102 103 /* 104 if ((p=smbw_getshared("RESOLVE_ORDER"))) 105 lp_set_name_resolve_order(p); 106 */ 107 return 0; 116 108 117 109 } … … 119 111 void smbwrp_initthread(void) 120 112 { 121 122 123 124 125 113 /* 114 * Block SIGPIPE (from lib/util_sock.c: write()) 115 * It is not needed and should not stop execution 116 */ 117 BlockSignals(True, SIGPIPE); 126 118 } 127 119 128 120 #if 0 129 /* ****************************************************130 remove redundent stuff from a filename131 *******************************************************/121 /* 122 * remove redundent stuff from a filename 123 */ 132 124 void clean_fname(char *name) 133 125 { 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 if (p2[0] == '/') break; 168 } 169 while (*p2) { 170 p2[0] = p2[3]; 171 p2++;172 } 173 174 175 if (strcmp(name,"/..")==0) { 176 modified = 1; 177 name[1] = 0;178 } 179 180 l = strlen(name); 181 p = l>=3?(name+l-3):name;182 if (strcmp(p,"/..")==0) { 183 modified = 1; 184 for (p2=p-1;p2>name;p2--) { 185 if (p2[0] == '/') break; 186 } 187 if (p2==name) { 188 p[0] = '/'; 189 p[1] = 0; 190 } else { 191 p2[0] = 0;192 } 193 } 194 195 l = strlen(name); 196 p = l>=2?(name+l-2):name;197 if (strcmp(p,"/.")==0) { 198 if (p == name) {199 p[1] = 0; 200 } else { 201 p[0] = 0; 202 } 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 126 char *p, *p2; 127 int l; 128 int modified = 1; 129 130 if (!name) return; 131 132 while (modified) { 133 modified = 0; 134 135 if ((p=strstr(name,"/./"))) { 136 modified = 1; 137 while (*p) { 138 p[0] = p[2]; 139 p++; 140 } 141 } 142 143 if ((p=strstr(name,"//"))) { 144 modified = 1; 145 while (*p) { 146 p[0] = p[1]; 147 p++; 148 } 149 } 150 151 if (strcmp(name,"/../")==0) { 152 modified = 1; 153 name[1] = 0; 154 } 155 156 if ((p=strstr(name,"/../"))) { 157 modified = 1; 158 for (p2=(p>name?p-1:p);p2>name;p2--) { 159 if (p2[0] == '/') 160 break; 161 } 162 while (*p2) { 163 p2[0] = p2[3]; 164 p2++; 165 } 166 } 167 168 if (strcmp(name,"/..")==0) { 169 modified = 1; 170 name[1] = 0; 171 } 172 173 l = strlen(name); 174 p = l >= 3 ? (name+l-3):name; 175 if (strcmp(p,"/..")==0) { 176 modified = 1; 177 for (p2=p-1;p2>name;p2--) { 178 if (p2[0] == '/') 179 break; 180 } 181 if (p2==name) { 182 p[0] = '/'; 183 p[1] = 0; 184 } else 185 p2[0] = 0; 186 } 187 188 l = strlen(name); 189 p = l >= 2 ? (name+l-2):name; 190 if (strcmp(p,"/.")==0) { 191 if (p == name) 192 p[1] = 0; 193 else 194 p[0] = 0; 195 } 196 197 if (strncmp(p=name,"./",2) == 0) { 198 modified = 1; 199 do { 200 p[0] = p[2]; 201 } while (*p++); 202 } 203 204 l = strlen(p=name); 205 if (l > 1 && p[l-1] == '/') { 206 modified = 1; 207 p[l-1] = 0; 208 } 209 } 218 210 } 219 211 #endif 220 212 221 /* ****************************************************222 return a connection to a server223 *******************************************************/213 /* 214 * return a connection to a server 215 */ 224 216 int _System smbwrp_connect( Resource* pRes, cli_state ** cli) 225 217 { 226 smbwrp_server * srv = &pRes->srv; 227 char * server = srv->server_name; 228 char * share = *(srv->share_name) ? srv->share_name : "IPC$"; 229 char * workgroup = srv->workgroup; 230 struct nmb_name called, calling; 231 char *p, *server_n = server; 232 fstring group; 233 struct sockaddr_storage ss; 234 struct cli_state * c; 235 char* dev_type; 236 int loginerror = 0; 237 NTSTATUS status; 238 239 zero_sockaddr(&ss); 240 241 debuglocal(1,"Connecting to \\\\%s:*********@%s:%s\\%s. Master %s:%d\n", srv->username, workgroup, server, share, srv->master, srv->ifmastergroup); 242 243 if (!*server) { 244 struct sockaddr_storage sip; 245 246 if (*workgroup) 247 { 248 if (!find_master_ip(workgroup, &sip)) { 249 return 1; 250 } 251 fstrcpy(group, inet_ntoa(sip.sin_addr)); 252 server_n = group; 253 } else 254 if (*srv->master) 255 { 256 if (srv->ifmastergroup) 257 { 258 if (!find_master_ip(srv->master, &sip)) { 259 return 11; 260 } 261 strncpy(srv->master, inet_ntoa(sip.sin_addr), sizeof(srv->master) - 1); 262 srv->ifmastergroup = 0; 263 } 264 server_n = srv->master; 265 } else 266 { 267 return 10; 268 } 269 } 270 271 make_nmb_name(&calling, global_myname(), 0x0); 272 // make_nmb_name(&calling, "WORK", 0x0); // this machine name 273 make_nmb_name(&called , server_n, 0x20); 218 smbwrp_server * srv = &pRes->srv; 219 char * server = srv->server_name; 220 char * share = *(srv->share_name) ? srv->share_name : "IPC$"; 221 char * workgroup = srv->workgroup; 222 struct nmb_name called, calling; 223 char *p, *server_n = server; 224 fstring group; 225 struct sockaddr_storage ss; 226 struct cli_state * c; 227 char* dev_type; 228 int loginerror = 0; 229 NTSTATUS status; 230 231 zero_sockaddr(&ss); 232 233 debuglocal(1,"Connecting to \\\\%s:*********@%s:%s\\%s. Master %s:%d\n", srv->username, workgroup, server, share, srv->master, srv->ifmastergroup); 234 235 if (!*server) { 236 struct sockaddr_storage sip; 237 238 if (*workgroup) 239 { 240 if (!find_master_ip(workgroup, &sip)) 241 return 1; 242 243 fstrcpy(group, inet_ntoa(sip.sin_addr)); 244 server_n = group; 245 } else if (*srv->master) 246 { 247 if (srv->ifmastergroup) 248 { 249 if (!find_master_ip(srv->master, &sip)) 250 return 11; 251 252 strncpy(srv->master, inet_ntoa(sip.sin_addr), sizeof(srv->master) - 1); 253 srv->ifmastergroup = 0; 254 } 255 server_n = srv->master; 256 } else 257 return 10; 258 } 259 260 make_nmb_name(&calling, global_myname(), 0x0); 261 //make_nmb_name(&calling, "WORK", 0x0); // this machine name 262 make_nmb_name(&called , server_n, 0x20); 274 263 275 264 again: 276 zero_sockaddr(&ss); 277 278 /* have to open a new connection */ 279 if (!(c=cli_initialise())) 280 { 281 return 2; 282 } 283 284 cli_set_timeout(c, 10000); /* 10 seconds. */ 285 286 if (pRes->krb5support == 1) 287 { 288 debuglocal(1,"Kerberos support enabled\n"); 289 c->use_kerberos = True; 290 } 291 292 if (!NT_STATUS_IS_OK(cli_connect(c, server_n, &ss))) 293 { 294 return 3; 295 } 296 297 if (!cli_session_request(c, &calling, &called)) { 298 cli_shutdown(c); 299 if (strcmp(called.name, "*SMBSERVER")) { 300 make_nmb_name(&called , "*SMBSERVER", 0x20); 301 goto again; 302 } 303 return 4; 304 } 305 306 debuglocal(4," session request ok\n"); 307 308 if (!NT_STATUS_IS_OK(cli_negprot(c))) { 309 cli_shutdown(c); 310 return 5; 311 } 312 313 debuglocal(4," session setuping for <%s>/<********> in <%s> %08x %08x %08x\n", srv->username, workgroup, c->protocol, c->sec_mode, c->capabilities); 314 315 if (!NT_STATUS_IS_OK(cli_session_setup(c, srv->username, 316 srv->password, strlen(srv->password), 317 srv->password, strlen(srv->password), 318 workgroup))) { 319 debuglocal(4,"%s/******** login failed\n", srv->username); 320 loginerror = 1; // save the login error 321 322 /* try an anonymous login if it failed */ 323 if (!NT_STATUS_IS_OK(cli_session_setup(c, "", "", 0,"", 0, workgroup))) { 324 debuglocal(4,"Anonymous login failed\n"); 325 cli_shutdown(c); 326 return 6; 327 } 328 debuglocal(4,"Anonymous login successful\n"); 329 status = cli_init_creds(c, "", lp_workgroup(), ""); 330 } else { 331 status = cli_init_creds(c, srv->username, workgroup, srv->password); 332 } 333 334 if (!NT_STATUS_IS_OK(status)) { 335 debuglocal(4,"cli_init_creds() failed\n"); 336 cli_shutdown(c); 337 // if loginerror is != 0 means normal login failed, but anonymous login worked 338 if (loginerror !=0) 339 return 6; 340 else 341 return 7; 342 } 343 344 debuglocal(4," session setup ok. Sending tconx <%s> <********>\n", share); 345 346 // YD ticket:58 we need to check resource type to avoid connecting to printers. 347 // dev type is set to IPC for IPC$, A: for everything else (printers use LPT1:) 348 if (!strcmp( share, "IPC$")) 349 dev_type = "IPC"; 350 else 351 dev_type = "A:"; 352 353 if (!NT_STATUS_IS_OK(cli_tcon_andx(c, share, dev_type, 354 srv->password, strlen(srv->password)+1))) { 355 cli_shutdown(c); 356 // if loginerror is != 0 means normal login failed, but anonymous login worked 357 if (loginerror !=0) 358 return 6; 359 else 360 return 7; 361 } 362 363 debuglocal(4," tconx ok. cli caps %08x\n", c->capabilities); 265 zero_sockaddr(&ss); 266 267 // have to open a new connection 268 if (!(c=cli_initialise())) 269 return 2; 270 271 cli_set_timeout(c, 10000); // 10 seconds 272 273 if (pRes->krb5support == 1) 274 { 275 debuglocal(1,"Kerberos support enabled\n"); 276 c->use_kerberos = True; 277 } 278 279 if (!NT_STATUS_IS_OK(cli_connect(c, server_n, &ss))) 280 return 3; 281 282 if (!cli_session_request(c, &calling, &called)) { 283 cli_shutdown(c); 284 if (strcmp(called.name, "*SMBSERVER")) { 285 make_nmb_name(&called , "*SMBSERVER", 0x20); 286 goto again; 287 } 288 return 4; 289 } 290 291 debuglocal(4," session request ok\n"); 292 293 if (!NT_STATUS_IS_OK(cli_negprot(c))) { 294 cli_shutdown(c); 295 return 5; 296 } 297 298 debuglocal(4," session setuping for <%s>/<********> in <%s> %08x %08x %08x\n", srv->username, workgroup, c->protocol, c->sec_mode, c->capabilities); 299 300 if (!NT_STATUS_IS_OK(cli_session_setup(c, srv->username, 301 srv->password, strlen(srv->password), 302 srv->password, strlen(srv->password), 303 workgroup))) 304 { 305 debuglocal(4,"%s/******** login failed\n", srv->username); 306 loginerror = 1; // save the login error 307 308 // try an anonymous login if it failed 309 if (!NT_STATUS_IS_OK(cli_session_setup(c, "", "", 0,"", 0, workgroup))) { 310 debuglocal(4,"Anonymous login failed\n"); 311 cli_shutdown(c); 312 return 6; 313 } 314 debuglocal(4,"Anonymous login successful\n"); 315 status = cli_init_creds(c, "", lp_workgroup(), ""); 316 } else { 317 status = cli_init_creds(c, srv->username, workgroup, srv->password); 318 } 319 320 if (!NT_STATUS_IS_OK(status)) { 321 debuglocal(4,"cli_init_creds() failed\n"); 322 cli_shutdown(c); 323 // if loginerror is != 0 means normal login failed, but anonymous login worked 324 if (loginerror !=0) 325 return 6; 326 else 327 return 7; 328 } 329 330 debuglocal(4," session setup ok. Sending tconx <%s> <********>\n", share); 331 332 // YD ticket:58 we need to check resource type to avoid connecting to printers. 333 // dev type is set to IPC for IPC$, A: for everything else (printers use LPT1:) 334 if (!strcmp( share, "IPC$")) 335 dev_type = "IPC"; 336 else 337 dev_type = "A:"; 338 339 if (!NT_STATUS_IS_OK(cli_tcon_andx(c, share, dev_type, 340 srv->password, strlen(srv->password)+1))) 341 { 342 cli_shutdown(c); 343 // if loginerror is != 0 means normal login failed, but anonymous login worked 344 if (loginerror !=0) 345 return 6; 346 else 347 return 7; 348 } 349 350 debuglocal(4," tconx ok. cli caps %08x\n", c->capabilities); 364 351 365 366 367 368 369 } 370 371 /* ****************************************************372 close a connection to a server373 *******************************************************/352 // save cli_state pointer 353 *cli = c; 354 355 return 0; 356 } 357 358 /* 359 * close a connection to a server 360 */ 374 361 void _System smbwrp_disconnect( Resource* pRes, cli_state * cli) 375 362 { 376 if (pRes && cli) 377 { 378 // this call will free all buffers, close handles and free cli mem 379 cli_shutdown( cli); 380 } 381 } 382 383 384 385 /***************************************************** 386 a wrapper for open() 387 *******************************************************/ 363 // this call will free all buffers, close handles and free cli mem 364 if (pRes && cli) 365 cli_shutdown( cli); 366 } 367 368 /* 369 * a wrapper for open() 370 */ 388 371 int _System smbwrp_open(cli_state * cli, smbwrp_file * file) 389 372 { 390 uint16_t fd = 0; 391 392 if (!cli || !file || !*file->fname) 393 { 394 return maperror(EINVAL); 395 } 396 if (file->denymode < DENY_ALL || file->denymode > DENY_NONE) 397 { 398 file->denymode = DENY_NONE; 399 } 400 401 debuglocal(4,"cli_open(%s) attr %08x mode %02x denymode %02x\n", file->fname, file->openattr, file->openmode, file->denymode); 402 if (!NT_STATUS_IS_OK(cli_open(cli, file->fname, file->openmode, file->denymode, &fd))) 403 { 404 return os2cli_errno(cli); 405 } 406 file->fd = fd; 407 file->updatetime = 0; 408 file->offset = 0; 409 return 0; 410 } 411 412 /***************************************************** 413 a wrapper for read() 414 *******************************************************/ 373 uint16_t fd = 0; 374 375 if (!cli || !file || !*file->fname) 376 return maperror(EINVAL); 377 378 if (file->denymode < DENY_ALL || file->denymode > DENY_NONE) 379 file->denymode = DENY_NONE; 380 381 debuglocal(4,"cli_open(%s) attr %08x mode %02x denymode %02x\n", file->fname, file->openattr, file->openmode, file->denymode); 382 if (!NT_STATUS_IS_OK(cli_open(cli, file->fname, file->openmode, file->denymode, &fd))) 383 return os2cli_errno(cli); 384 385 file->fd = fd; 386 file->updatetime = 0; 387 file->offset = 0; 388 return 0; 389 } 390 391 /* 392 * a wrapper for read() 393 */ 415 394 int _System smbwrp_read(cli_state * cli, smbwrp_file * file, void *buf, unsigned long count, unsigned long * result) 416 395 { 417 int ret; 418 419 if (!cli || !file || !buf || !result) 420 { 421 return maperror(EINVAL); 422 } 396 int ret; 397 398 if (!cli || !file || !buf || !result) 399 return maperror(EINVAL); 423 400 424 *result = 0; 425 ret = cli_read(cli, file->fd, buf, file->offset, count); 426 if (ret == -1) 427 { 428 return os2cli_errno(cli); 429 } 430 431 file->offset += ret; 432 *result = ret; 433 return 0; 434 } 435 401 *result = 0; 402 ret = cli_read(cli, file->fd, buf, file->offset, count); 403 if (ret == -1) 404 return os2cli_errno(cli); 405 406 file->offset += ret; 407 *result = ret; 408 return 0; 409 } 410 411 /* 412 * a wrapper for write() 413 */ 414 int _System smbwrp_write(cli_state * cli, smbwrp_file * file, void *buf, unsigned long count, unsigned long * result) 415 { 416 NTSTATUS status; 417 size_t ret; 418 419 if (!cli || !file || !buf || !result) 420 return maperror(EINVAL); 436 421 437 438 /***************************************************** 439 a wrapper for write() 440 *******************************************************/ 441 int _System smbwrp_write(cli_state * cli, smbwrp_file * file, void *buf, unsigned long count, unsigned long * result) 442 { 443 NTSTATUS status; 444 size_t ret; 445 446 if (!cli || !file || !buf || !result) 447 { 448 return maperror(EINVAL); 449 } 422 *result = 0; 423 //debuglocal(1,("Write %x %d %lld %d", cli, file->fd, file->offset, count)); 424 status = cli_writeall(cli, file->fd, 0, buf, file->offset, count, &ret); 425 if (!NT_STATUS_IS_OK(status)) 426 return os2cli_errno(cli); 427 428 file->updatetime = 1; 429 file->offset += ret; 430 *result = ret; 431 return 0; 432 } 433 434 /* 435 * a wrapper for close() 436 */ 437 int _System smbwrp_close(cli_state * cli, smbwrp_file * file) 438 { 439 int rc = 0; 440 if (!cli || !file) 441 return maperror(EINVAL); 442 443 debuglocal(4,"smpwrp_close updatetime: %d\n", file->updatetime); 444 445 if (file->updatetime == 1) 446 { 447 file->mtime = time(NULL); 448 debuglocal(4,"cli_close new mtime %lu\n", file->mtime); 449 } 450 450 451 *result = 0; 452 //debuglocal(1,("Write %x %d %lld %d", cli, file->fd, file->offset, count)); 453 status = cli_writeall(cli, file->fd, 0, buf, file->offset, count, &ret); 454 if (!NT_STATUS_IS_OK(status)) { 455 return os2cli_errno(cli); 456 } 457 458 file->updatetime = 1; 459 file->offset += ret; 460 *result = ret; 461 return 0; 462 } 463 464 /***************************************************** 465 a wrapper for close() 466 *******************************************************/ 467 int _System smbwrp_close(cli_state * cli, smbwrp_file * file) 468 { 469 int rc = 0; 470 if (!cli || !file) 471 { 472 return maperror(EINVAL); 473 } 474 475 debuglocal(4,"smpwrp_close updatetime: %d\n", file->updatetime); 476 477 if (file->updatetime == 1) 478 { 479 file->mtime = time(NULL); 480 debuglocal(4,"cli_close new mtime %lu\n", file->mtime); 481 } 451 if (!NT_STATUS_IS_OK(cli_close(cli, file->fd))) 452 rc = os2cli_errno(cli); 453 454 if (!rc && (file->openattr || file->mtime || file->ctime)) 455 { 456 debuglocal(4,"Set pathinfo on close %s %08x %d %d\n", file->fname, file->openattr, file->mtime, file->ctime); 457 if (!NT_STATUS_IS_OK(cli_setpathinfo_basic(cli, file->fname, file->ctime, 0, file->mtime, 0, file->openattr))) 458 debuglocal(4,"Set pathinfo on close failed %d\n", os2cli_errno(cli)); 459 } 460 461 file->openattr = 0; 462 file->mtime = 0; 463 file->ctime = 0; 464 file->updatetime = 0; 465 file->fd = -1; 466 file->offset = 0; 467 *file->fname = 0; 468 return rc; 469 } 470 471 int _System smbwrp_setfilesize(cli_state * cli, smbwrp_file * file, long long newsize) 472 { 473 int rc = 0; 474 if (!cli || !file) 475 return maperror(EINVAL); 476 477 debuglocal(4,"cli_setnewfilesize(%s) %lld\n", file->fname, newsize); 478 if (!NT_STATUS_IS_OK(cli_ftruncate(cli, file->fd, newsize))) 479 { 480 if (newsize) 481 rc = os2cli_errno(cli); 482 483 if (!NT_STATUS_IS_OK(cli_close(cli, file->fd))) 484 return os2cli_errno(cli); 485 486 uint16_t fd = 0; 487 file->fd = -1; 488 file->offset = 0; 489 file->openmode &= ~(O_CREAT | O_EXCL); 490 file->openmode |= O_TRUNC; 491 debuglocal(4,"cli_setnewfileszie : cli_open(%s) attr %08x mode %02x denymode %02x\n", file->fname, file->openattr, file->openmode, file->denymode); 492 if (!NT_STATUS_IS_OK(cli_open(cli, file->fname, file->openmode, file->denymode, &fd))) 493 return os2cli_errno(cli); 494 495 file->fd = fd; 496 } 497 return 0; 498 } 499 500 /* 501 * a wrapper for rename() 502 */ 503 int _System smbwrp_rename(cli_state * cli, char *oldname, char *newname) 504 { 505 if (!cli || !oldname || !newname) 506 return maperror(EINVAL); 507 508 debuglocal(1,"Rename <%s> -> <%s>\n", oldname, newname); 509 if (!NT_STATUS_IS_OK(cli_rename(cli, oldname, newname))) 510 return os2cli_errno(cli); 511 512 return 0; 513 } 514 515 516 /* 517 * a wrapper for chmod() 518 */ 519 int _System smbwrp_setattr(cli_state * cli, smbwrp_fileinfo *finfo) 520 { 521 if (!cli || !finfo || !*finfo->fname) 522 return maperror(EINVAL); 523 524 debuglocal(4,"Setting on <%s> attr %04x, time %lu (timezone /%lu\n", finfo->fname, finfo->attr, finfo->mtime, finfo->mtime + get_time_zone(finfo->mtime)); 525 // we already have gmt time, so no need to add timezone 526 // if (!cli_setatr(cli, finfo->fname, finfo->attr, finfo->mtime + (finfo->mtime == 0 ? 0 : get_time_zone(finfo->mtime))) 527 if (!NT_STATUS_IS_OK(cli_setatr(cli, finfo->fname, finfo->attr, finfo->mtime)) 528 && !NT_STATUS_IS_OK(cli_setatr(cli, finfo->fname, finfo->attr, 0))) 529 return os2cli_errno(cli); 482 530 483 if (!NT_STATUS_IS_OK(cli_close(cli, file->fd))) 484 { 485 rc = os2cli_errno(cli); 486 } 487 488 if (!rc && (file->openattr || file->mtime || file->ctime)) 489 { 490 debuglocal(4,"Set pathinfo on close %s %08x %d %d\n", file->fname, file->openattr, file->mtime, file->ctime); 491 if (!NT_STATUS_IS_OK(cli_setpathinfo_basic(cli, file->fname, file->ctime, 0, file->mtime, 0, file->openattr))) 492 { 493 debuglocal(4,"Set pathinfo on close failed %d\n", os2cli_errno(cli)); 494 //rc = os2cli_errno(cli); 495 } 496 } 497 498 file->openattr = 0; 499 file->mtime = 0; 500 file->ctime = 0; 501 file->updatetime = 0; 502 file->fd = -1; 503 file->offset = 0; 504 *file->fname = 0; 505 return rc; 506 } 507 508 int _System smbwrp_setfilesize(cli_state * cli, smbwrp_file * file, long long newsize) 509 { 510 int rc = 0; 511 if (!cli || !file) 512 { 513 return maperror(EINVAL); 514 } 515 516 debuglocal(4,"cli_setnewfilesize(%s) %lld\n", file->fname, newsize); 517 if (!NT_STATUS_IS_OK(cli_ftruncate(cli, file->fd, newsize))) 518 { 519 if (newsize) 520 { 521 rc = os2cli_errno(cli); 522 } 523 524 if (!NT_STATUS_IS_OK(cli_close(cli, file->fd))) 525 { 526 return os2cli_errno(cli); 527 } 528 uint16_t fd = 0; 529 file->fd = -1; 530 file->offset = 0; 531 file->openmode &= ~(O_CREAT | O_EXCL); 532 file->openmode |= O_TRUNC; 533 debuglocal(4,"cli_setnewfileszie : cli_open(%s) attr %08x mode %02x denymode %02x\n", file->fname, file->openattr, file->openmode, file->denymode); 534 if (!NT_STATUS_IS_OK(cli_open(cli, file->fname, file->openmode, file->denymode, &fd))) 535 { 536 return os2cli_errno(cli); 537 } 538 file->fd = fd; 539 } 540 return 0; 541 } 542 543 /***************************************************** 544 a wrapper for rename() 545 *******************************************************/ 546 int _System smbwrp_rename(cli_state * cli, char *oldname, char *newname) 547 { 548 if (!cli || !oldname || !newname) 549 { 550 return maperror(EINVAL); 551 } 552 553 debuglocal(1,"Rename <%s> -> <%s>\n", oldname, newname); 554 if (!NT_STATUS_IS_OK(cli_rename(cli, oldname, newname))) 555 { 556 return os2cli_errno(cli); 557 } 558 return 0; 559 } 560 561 562 /***************************************************** 563 a wrapper for chmod() 564 *******************************************************/ 565 int _System smbwrp_setattr(cli_state * cli, smbwrp_fileinfo *finfo) 566 { 567 if (!cli || !finfo || !*finfo->fname) 568 { 569 return maperror(EINVAL); 570 } 571 572 debuglocal(4,"Setting on <%s> attr %04x, time %lu (timezone /%lu\n", finfo->fname, finfo->attr, finfo->mtime, finfo->mtime + get_time_zone(finfo->mtime)); 573 // we already have gmt time, so no need to add timezone 574 // if (!cli_setatr(cli, finfo->fname, finfo->attr, finfo->mtime + (finfo->mtime == 0 ? 0 : get_time_zone(finfo->mtime))) 575 if (!NT_STATUS_IS_OK(cli_setatr(cli, finfo->fname, finfo->attr, finfo->mtime)) 576 && !NT_STATUS_IS_OK(cli_setatr(cli, finfo->fname, finfo->attr, 0))) 577 { 578 return os2cli_errno(cli); 579 } 580 return 0; 581 } 582 583 /***************************************************** 584 a wrapper for unlink() 585 *******************************************************/ 531 return 0; 532 } 533 534 /* 535 * a wrapper for unlink() 536 */ 586 537 int _System smbwrp_unlink(cli_state * cli, const char *fname) 587 538 { 588 if (!cli || !fname) 589 { 590 return maperror(EINVAL); 591 } 539 if (!cli || !fname) 540 return maperror(EINVAL); 541 592 542 #if 0 593 if (strncmp(cli->dev, "LPT", 3) == 0) 594 { 595 int job = smbw_stat_printjob(cli, fname, NULL, NULL); 596 if (job == -1) 597 { 598 goto failed; 599 } 600 if (cli_printjob_del(cli, job) != 0) 601 { 602 goto failed; 603 } 604 } else 543 if (strncmp(cli->dev, "LPT", 3) == 0) 544 { 545 int job = smbw_stat_printjob(cli, fname, NULL, NULL); 546 if (job == -1) 547 goto failed; 548 549 if (cli_printjob_del(cli, job) != 0) 550 goto failed; 551 552 } else 605 553 #endif 606 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) 607 { 608 return os2cli_errno(cli); 609 } 610 return 0; 611 } 612 613 /***************************************************** 614 a wrapper for lseek() 615 *******************************************************/ 554 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) 555 return os2cli_errno(cli); 556 557 return 0; 558 } 559 560 /* 561 * a wrapper for lseek() 562 */ 616 563 int _System smbwrp_lseek(cli_state * cli, smbwrp_file * file, int whence, long long offset) 617 564 { 618 off_t size; 619 if (!cli || !file) 620 { 621 return maperror(EINVAL); 622 } 623 624 debuglocal(4,"lseek %d %lld %lld\n", whence, offset, file->offset); 625 626 switch (whence) { 627 case SEEK_SET: 628 if (offset < 0) 629 { 630 return maperror(EINVAL); 631 } 632 file->offset = offset; 633 break; 634 case SEEK_CUR: 635 file->offset += offset; 636 break; 637 case SEEK_END: 638 if (offset > 0) 639 { 640 return maperror(EINVAL); 641 } 642 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(cli, file->fd, 643 NULL, &size, NULL, NULL, NULL, 644 NULL, NULL)) && 645 !NT_STATUS_IS_OK(cli_getattrE(cli, file->fd, 646 NULL, &size, NULL, NULL, NULL))) 647 { 648 return os2cli_errno(cli); 649 } 650 file->offset = size + offset; 651 break; 652 default: return maperror(EINVAL); 653 } 654 655 return 0; 656 } 657 658 /***************************************************** 659 try to do a QPATHINFO and if that fails then do a getatr 660 this is needed because win95 sometimes refuses the qpathinfo 661 *******************************************************/ 565 off_t size; 566 if (!cli || !file) 567 return maperror(EINVAL); 568 569 debuglocal(4,"lseek %d %lld %lld\n", whence, offset, file->offset); 570 571 switch (whence) { 572 case SEEK_SET: 573 if (offset < 0) 574 return maperror(EINVAL); 575 file->offset = offset; 576 break; 577 case SEEK_CUR: 578 file->offset += offset; 579 break; 580 case SEEK_END: 581 if (offset > 0) 582 return maperror(EINVAL); 583 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(cli, file->fd, 584 NULL, &size, NULL, NULL, NULL,NULL, NULL)) && 585 !NT_STATUS_IS_OK(cli_getattrE(cli, file->fd, 586 NULL, &size, NULL, NULL, NULL))) 587 return os2cli_errno(cli); 588 file->offset = size + offset; 589 break; 590 default: 591 return maperror(EINVAL); 592 } 593 594 return 0; 595 } 596 597 /* 598 * try to do a QPATHINFO and if that fails then do a getatr 599 * this is needed because win95 sometimes refuses the qpathinfo 600 */ 662 601 int _System smbwrp_getattr(smbwrp_server *srv, cli_state * cli, smbwrp_fileinfo *finfo) 663 602 { 664 SMB_INO_T ino = 0; 665 struct timespec ctime; 666 struct timespec mtime; 667 struct timespec atime; 668 669 if (!cli || !finfo || !*finfo->fname) 670 { 671 return maperror(EINVAL); 672 } 673 debuglocal(4,"getattr %d %d <%s>\n", cli->capabilities & CAP_NOPATHINFO2, cli->capabilities & CAP_NT_SMBS, finfo->fname); 674 if (!(cli->capabilities & CAP_NOPATHINFO2) && 675 NT_STATUS_IS_OK(cli_qpathinfo2(cli, finfo->fname, &ctime, &atime, &mtime, NULL, 676 (off_t *)&finfo->size, (unsigned short *)&finfo->attr, &ino))) 677 { 678 finfo->attr &= 0x7F; 679 finfo->ctime = convert_timespec_to_time_t(ctime); 680 finfo->atime = convert_timespec_to_time_t(atime); 681 finfo->mtime = convert_timespec_to_time_t(mtime); 682 return 0; 683 } 684 685 if (cli->fd == -1) 686 { 687 /* fd == -1 means the connection is broken */ 688 return maperror(ENOTCONN); 689 } 690 691 /* If the path is not on a share (it is a workgroup or a server), 692 * then cli_qpathinfo2 obviously fails. Return some fake information 693 * about the directory. 694 */ 695 if ( *srv->server_name == 0 696 || (strcmp(cli->dev,"IPC") == 0) 697 || *srv->share_name == 0 698 || (stricmp(srv->share_name,"IPC$") == 0) 699 || (strncmp(cli->dev,"LPT",3) == 0) 700 ) 701 { 702 debuglocal(4,"getattr not a share.\n"); 703 *(time_t *)&finfo->ctime = time (NULL); 704 *(time_t *)&finfo->atime = time (NULL); 705 *(time_t *)&finfo->mtime = time (NULL); 706 finfo->size = 0; 707 finfo->easize = 0; 708 finfo->attr = aDIR; 709 return 0; 710 } 603 SMB_INO_T ino = 0; 604 struct timespec ctime; 605 struct timespec mtime; 606 struct timespec atime; 607 608 if (!cli || !finfo || !*finfo->fname) 609 return maperror(EINVAL); 610 611 debuglocal(4,"getattr %d %d <%s>\n", cli->capabilities & CAP_NOPATHINFO2, cli->capabilities & CAP_NT_SMBS, finfo->fname); 612 if (!(cli->capabilities & CAP_NOPATHINFO2) && 613 NT_STATUS_IS_OK(cli_qpathinfo2(cli, finfo->fname, &ctime, &atime, 614 &mtime, NULL, (off_t *)&finfo->size, (unsigned short *)&finfo->attr, 615 &ino))) 616 { 617 finfo->attr &= 0x7F; 618 finfo->ctime = convert_timespec_to_time_t(ctime); 619 finfo->atime = convert_timespec_to_time_t(atime); 620 finfo->mtime = convert_timespec_to_time_t(mtime); 621 return 0; 622 } 623 624 // fd == -1 means the connection is broken */ 625 if (cli->fd == -1) 626 return maperror(ENOTCONN); 627 628 /* If the path is not on a share (it is a workgroup or a server), 629 * then cli_qpathinfo2 obviously fails. Return some fake information 630 * about the directory. 631 */ 632 if (*srv->server_name == 0 633 || (strcmp(cli->dev,"IPC") == 0) 634 || *srv->share_name == 0 635 || (stricmp(srv->share_name,"IPC$") == 0) 636 || (strncmp(cli->dev,"LPT",3) == 0)) 637 { 638 debuglocal(4,"getattr not a share.\n"); 639 *(time_t *)&finfo->ctime = time (NULL); 640 *(time_t *)&finfo->atime = time (NULL); 641 *(time_t *)&finfo->mtime = time (NULL); 642 finfo->size = 0; 643 finfo->easize = 0; 644 finfo->attr = aDIR; 645 return 0; 646 } 711 647 712 /* if this is NT then don't bother with the getatr */ 713 if (cli->capabilities & CAP_NT_SMBS && !(cli->capabilities & CAP_NOPATHINFO2)) 714 { 715 int ret = cli_errno(cli); 716 // cli_qpathinfo* reports EINVAL when path of given file not exists 717 // thus there is no real situation when EINVAL should be returned to 718 // client at this point, we just replace it to ENOTDIR 719 if (ret == EINVAL) 720 { 721 ret = ENOTDIR; 722 } 723 return maperror(ret); 724 } 725 726 if (NT_STATUS_IS_OK(cli_getatr(cli, finfo->fname, (unsigned short *)&finfo->attr, &finfo->size, (time_t *)&finfo->mtime))) 727 { 728 //debuglocal(2,("gotattr1 %08x <%s>\n", finfo->attr, finfo->fname)); 729 finfo->mtime -= get_time_zone(finfo->mtime); 730 finfo->atime = finfo->atime; //was mtime 731 finfo->ctime = finfo->ctime; //was mtime 732 cli->capabilities &= CAP_NOPATHINFO2; 733 return 0; 734 } 735 return os2cli_errno(cli); 736 } 737 738 /***************************************************** 739 try to do a QPATHINFO and if that fails then do a getatr 740 this is needed because win95 sometimes refuses the qpathinfo 741 *******************************************************/ 648 // if this is NT then don't bother with the getatr */ 649 if (cli->capabilities & CAP_NT_SMBS && !(cli->capabilities & CAP_NOPATHINFO2)) 650 { 651 int ret = cli_errno(cli); 652 /* 653 * cli_qpathinfo* reports EINVAL when path of given file not exists 654 * thus there is no real situation when EINVAL should be returned to 655 * client at this point, we just replace it to ENOTDIR 656 */ 657 if (ret == EINVAL) 658 ret = ENOTDIR; 659 660 return maperror(ret); 661 } 662 663 if (NT_STATUS_IS_OK(cli_getatr(cli, finfo->fname, (unsigned short *)&finfo->attr, &finfo->size, (time_t *)&finfo->mtime))) 664 { 665 //debuglocal(2,("gotattr1 %08x <%s>\n", finfo->attr, finfo->fname)); 666 finfo->mtime -= get_time_zone(finfo->mtime); 667 finfo->atime = finfo->atime; //was mtime 668 finfo->ctime = finfo->ctime; //was mtime 669 cli->capabilities &= CAP_NOPATHINFO2; 670 return 0; 671 } 672 673 return os2cli_errno(cli); 674 } 675 676 /* 677 * try to do a QPATHINFO and if that fails then do a getatr 678 * this is needed because win95 sometimes refuses the qpathinfo 679 */ 742 680 int _System smbwrp_fgetattr(cli_state * cli, smbwrp_file *file, smbwrp_fileinfo *finfo) 743 681 { 744 struct timespec ctime; 745 struct timespec mtime; 746 struct timespec atime; 747 SMB_INO_T ino = 0; 748 749 if (!cli || !file || !finfo) 750 { 751 return maperror(EINVAL); 752 } 753 754 strncpy(finfo->fname, file->fname, sizeof(finfo->fname) - 1); 755 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(cli, file->fd, 756 (unsigned short *)&finfo->attr, (off_t *)&finfo->size, &ctime, &atime, &mtime, NULL, 757 &ino))) 758 { 759 if (!NT_STATUS_IS_OK(cli_getattrE(cli, file->fd, 760 (unsigned short *)&finfo->attr, (&finfo->size), (time_t *)&finfo->ctime, (time_t *)&finfo->atime, (time_t *)&finfo->mtime))) 761 { 762 return os2cli_errno(cli); 763 } 764 else 765 { 766 finfo->ctime -= get_time_zone(finfo->ctime); 767 finfo->atime -= get_time_zone(finfo->atime); 768 finfo->mtime -= get_time_zone(finfo->mtime); 769 } 770 } 771 else 772 { 773 finfo->ctime = convert_timespec_to_time_t(ctime); 774 finfo->atime = convert_timespec_to_time_t(atime); 775 finfo->mtime = convert_timespec_to_time_t(mtime); 776 } 777 778 return 0; 682 struct timespec ctime; 683 struct timespec mtime; 684 struct timespec atime; 685 SMB_INO_T ino = 0; 686 687 if (!cli || !file || !finfo) 688 return maperror(EINVAL); 689 690 691 strncpy(finfo->fname, file->fname, sizeof(finfo->fname) - 1); 692 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(cli, file->fd, 693 (unsigned short *)&finfo->attr, (off_t *)&finfo->size, &ctime, 694 &atime, &mtime, NULL, &ino))) 695 { 696 if (!NT_STATUS_IS_OK(cli_getattrE(cli, file->fd, 697 (unsigned short *)&finfo->attr, (&finfo->size), 698 (time_t *)&finfo->ctime, (time_t *)&finfo->atime, 699 (time_t *)&finfo->mtime))) 700 return os2cli_errno(cli); 701 else 702 { 703 finfo->ctime -= get_time_zone(finfo->ctime); 704 finfo->atime -= get_time_zone(finfo->atime); 705 finfo->mtime -= get_time_zone(finfo->mtime); 706 } 707 } 708 else 709 { 710 finfo->ctime = convert_timespec_to_time_t(ctime); 711 finfo->atime = convert_timespec_to_time_t(atime); 712 finfo->mtime = convert_timespec_to_time_t(mtime); 713 } 714 715 return 0; 779 716 } 780 717 781 718 // =============================DIRECTORY ROUTINES============================ 782 719 783 /* ****************************************************784 add a entry to a directory listing785 *******************************************************/720 /* 721 * add a entry to a directory listing 722 */ 786 723 static void smbwrp_dir_add(const char* mnt, smbwrp_fileinfo *finfo, const char *mask, void *state) 787 724 { 788 if (state && finfo) 789 { 790 filelist_state * st = (filelist_state *)state; 791 char fullname[ _MAX_PATH] = {0}; 792 debuglocal(8,"adding <%s> %d %d %d\n", finfo->fname, sizeof(st->finfo), st->datalen, sizeof(st->finfo.fname)); 793 memcpy(&st->finfo, finfo, sizeof(st->finfo)); 794 strncpy(fullname, st->dir, strlen(st->dir)); 795 strncat(fullname, finfo->fname, sizeof(fullname) - strlen(fullname) -1); 796 strncpy(st->finfo.fname, fullname, sizeof(st->finfo.fname)); 797 getfindinfoL( st->pConn, st->plist, &st->finfo, st->ulAttribute, st->dir_mask); 798 } 725 if (state && finfo) 726 { 727 filelist_state * st = (filelist_state *)state; 728 char fullname[ _MAX_PATH] = {0}; 729 debuglocal(8,"adding <%s> %d %d %d\n", finfo->fname, sizeof(st->finfo), st->datalen, sizeof(st->finfo.fname)); 730 memcpy(&st->finfo, finfo, sizeof(st->finfo)); 731 strncpy(fullname, st->dir, strlen(st->dir)); 732 strncat(fullname, finfo->fname, sizeof(fullname) - strlen(fullname) -1); 733 strncpy(st->finfo.fname, fullname, sizeof(st->finfo.fname)); 734 getfindinfoL( st->pConn, st->plist, &st->finfo, st->ulAttribute, st->dir_mask); 735 } 736 return; 799 737 } 800 738 801 739 static void smbwrp_special_add(const char * name, void * state) 802 740 { 803 smbwrp_fileinfo finfo = {0}; 804 805 if (!name) 806 { 807 return; 808 } 809 810 ZERO_STRUCT(finfo); 811 812 strncpy(finfo.fname, name, sizeof(finfo.fname) - 1); 813 finfo.attr = aRONLY | aDIR; 814 815 smbwrp_dir_add("", &finfo, NULL, state); 741 smbwrp_fileinfo finfo = {0}; 742 743 if (!name) 744 return; 745 746 ZERO_STRUCT(finfo); 747 748 strncpy(finfo.fname, name, sizeof(finfo.fname) - 1); 749 finfo.attr = aRONLY | aDIR; 750 751 smbwrp_dir_add("", &finfo, NULL, state); 752 return; 816 753 } 817 754 818 755 static void smbwrp_printjob_add(struct print_job_info *job, void * state) 819 756 { 820 smbwrp_fileinfo finfo = {0}; 821 822 ZERO_STRUCT(finfo); 823 824 //printf("Printjob <%s>\n", job->name); 825 826 strncpy(finfo.fname, job->name, sizeof(finfo.fname) - 1); 827 finfo.mtime = job->t - get_time_zone(job->t); 828 finfo.atime = finfo.atime; //was mtime 829 finfo.ctime = finfo.ctime; //was mtime 830 finfo.attr = aRONLY; 831 finfo.size = job->size; 832 833 smbwrp_dir_add("", &finfo, NULL, state); 757 smbwrp_fileinfo finfo = {0}; 758 759 ZERO_STRUCT(finfo); 760 761 //printf("Printjob <%s>\n", job->name); 762 763 strncpy(finfo.fname, job->name, sizeof(finfo.fname) - 1); 764 finfo.mtime = job->t - get_time_zone(job->t); 765 finfo.atime = finfo.atime; //was mtime 766 finfo.ctime = finfo.ctime; //was mtime 767 finfo.attr = aRONLY; 768 finfo.size = job->size; 769 770 smbwrp_dir_add("", &finfo, NULL, state); 771 return; 834 772 } 835 773 … … 837 775 const char *comment, void *state) 838 776 { 839 smbwrp_fileinfo finfo = {0}; 840 841 // strip administrative names and printers from list 842 if (type == STYPE_PRINTQ || strcmp(share,"IPC$") == 0) return; 843 844 ZERO_STRUCT(finfo); 845 846 strncpy(finfo.fname, share, sizeof(finfo.fname) - 1); 847 finfo.attr = aRONLY | aDIR; 848 849 smbwrp_dir_add("", &finfo, NULL, state); 850 } 851 852 /**************************************************************************** 853 Do a directory listing, calling fn on each file found. 854 Modified from cli_list 855 ****************************************************************************/ 777 smbwrp_fileinfo finfo = {0}; 778 779 // strip administrative names and printers from list 780 if (type == STYPE_PRINTQ || strcmp(share,"IPC$") == 0) 781 return; 782 783 ZERO_STRUCT(finfo); 784 785 strncpy(finfo.fname, share, sizeof(finfo.fname) - 1); 786 finfo.attr = aRONLY | aDIR; 787 788 smbwrp_dir_add("", &finfo, NULL, state); 789 return; 790 } 791 792 /* 793 * Do a directory listing, calling fn on each file found. 794 * Modified from cli_list 795 */ 856 796 static int list_files(struct cli_state *cli, const char *mask, uint16 attribute, 857 797 void (*fn)(const char *, smbwrp_fileinfo *, const char *, 858 798 void *), void *state) 859 799 { 860 TALLOC_CTX *frame = talloc_stackframe(); 861 struct event_context *ev; 862 struct tevent_req *req; 863 NTSTATUS status = NT_STATUS_NO_MEMORY; 864 struct file_info *finfo; 865 size_t i, num_finfo; 866 uint16_t info_level; 867 void *dircachectx = NULL; 868 smbwrp_fileinfo wrpfinfo; 869 870 /* Try to get the listing from cache. */ 871 if (dircache_list_files(fn, state, &num_finfo)) 872 { 873 /* Got from cache. */ 874 return(num_finfo); 875 } 876 877 if (cli_has_async_calls(cli)) { 878 /* 879 * Can't use sync call while an async call is in flight 880 */ 881 status = NT_STATUS_INVALID_PARAMETER; 882 goto fail; 883 } 884 ev = event_context_init(frame); 885 if (ev == NULL) { 886 goto fail; 887 } 888 889 info_level = (cli->capabilities & CAP_NT_SMBS) 890 ? SMB_FIND_FILE_BOTH_DIRECTORY_INFO : SMB_FIND_EA_SIZE; 891 892 debuglocal(4,"list_files level %d. mask <%s>\n", info_level, mask); 893 894 req = cli_list_send(frame, ev, cli, mask, attribute, info_level); 895 if (req == NULL) { 896 goto fail; 897 } 898 if (!tevent_req_poll(req, ev)) { 899 status = map_nt_error_from_unix(errno); 900 goto fail; 901 } 902 903 status = cli_list_recv(req, frame, &finfo, &num_finfo); 904 if (!NT_STATUS_IS_OK(status)) { 905 goto fail; 906 } 907 908 dircachectx = dircache_write_begin(state, num_finfo); 909 910 debuglocal(4,"list_files: got %d files\n", num_finfo); 911 912 913 for (i=0; i<num_finfo; i++) { 914 //as samba and this client have different finfo, we need to convert 915 memset(&wrpfinfo, 0, sizeof(wrpfinfo)); 916 wrpfinfo.size = finfo[i].size; 917 wrpfinfo.attr = finfo[i].mode; 918 wrpfinfo.ctime = convert_timespec_to_time_t(finfo[i].ctime_ts); 919 wrpfinfo.mtime = convert_timespec_to_time_t(finfo[i].mtime_ts); 920 wrpfinfo.atime = convert_timespec_to_time_t(finfo[i].atime_ts); 921 wrpfinfo.easize = finfo[i].easize; 922 strncpy(wrpfinfo.fname, finfo[i].name, sizeof(wrpfinfo.fname) -1); 923 924 fn(cli->dfs_mountpoint, &wrpfinfo, mask, state); 925 // Also add the entry to the cache. 926 dircache_write_entry(dircachectx, &wrpfinfo); 927 } 928 929 dircache_write_end(dircachectx); 800 TALLOC_CTX *frame = talloc_stackframe(); 801 struct event_context *ev; 802 struct tevent_req *req; 803 NTSTATUS status = NT_STATUS_NO_MEMORY; 804 struct file_info *finfo; 805 size_t i, num_finfo; 806 uint16_t info_level; 807 void *dircachectx = NULL; 808 smbwrp_fileinfo wrpfinfo; 809 810 // Try to get the listing from cache. 811 if (dircache_list_files(fn, state, &num_finfo)) 812 return(num_finfo); // Got from cache 813 814 if (cli_has_async_calls(cli)) { 815 /* 816 * Can't use sync call while an async call is in flight 817 */ 818 status = NT_STATUS_INVALID_PARAMETER; 819 goto fail; 820 } 821 ev = event_context_init(frame); 822 if (ev == NULL) 823 goto fail; 824 825 info_level = (cli->capabilities & CAP_NT_SMBS) 826 ? SMB_FIND_FILE_BOTH_DIRECTORY_INFO : SMB_FIND_EA_SIZE; 827 828 debuglocal(4,"list_files level %d. mask <%s>\n", info_level, mask); 829 830 req = cli_list_send(frame, ev, cli, mask, attribute, info_level); 831 if (req == NULL) 832 goto fail; 833 834 if (!tevent_req_poll(req, ev)) { 835 status = map_nt_error_from_unix(errno); 836 goto fail; 837 } 838 839 status = cli_list_recv(req, frame, &finfo, &num_finfo); 840 if (!NT_STATUS_IS_OK(status)) 841 goto fail; 842 843 dircachectx = dircache_write_begin(state, num_finfo); 844 845 debuglocal(4,"list_files: got %d files\n", num_finfo); 846 847 for (i=0; i<num_finfo; i++) { 848 //as samba and this client have different finfo, we need to convert 849 memset(&wrpfinfo, 0, sizeof(wrpfinfo)); 850 wrpfinfo.size = finfo[i].size; 851 wrpfinfo.attr = finfo[i].mode; 852 wrpfinfo.ctime = convert_timespec_to_time_t(finfo[i].ctime_ts); 853 wrpfinfo.mtime = convert_timespec_to_time_t(finfo[i].mtime_ts); 854 wrpfinfo.atime = convert_timespec_to_time_t(finfo[i].atime_ts); 855 wrpfinfo.easize = finfo[i].easize; 856 strncpy(wrpfinfo.fname, finfo[i].name, sizeof(wrpfinfo.fname) -1); 857 fn(cli->dfs_mountpoint, &wrpfinfo, mask, state); 858 // Also add the entry to the cache. 859 dircache_write_entry(dircachectx, &wrpfinfo); 860 } 861 862 dircache_write_end(dircachectx); 930 863 fail: 931 932 933 } 934 935 /* ****************************************************936 open a directory on the server937 *******************************************************/864 TALLOC_FREE(frame); 865 return num_finfo; 866 } 867 868 /* 869 * open a directory on the server 870 */ 938 871 int _System smbwrp_filelist(smbwrp_server *srv, cli_state * cli, filelist_state * state) 939 872 { 940 if (!srv || !cli || !state || !*state->mask) 941 { 942 return maperror(EINVAL); 943 } 944 debuglocal(1,"Filelist <%s> on master <%s> wgrp <%s> server <%s> share <%s> clidev <%s>\n", state->mask, srv->master, srv->workgroup, srv->server_name, srv->share_name, cli->dev); 945 if (*srv->workgroup == 0 && *srv->server_name == 0) 946 { 947 smbwrp_special_add(".", state); 948 smbwrp_special_add("..", state); 949 cli_NetServerEnum(cli, srv->master, SV_TYPE_DOMAIN_ENUM, 950 smbwrp_share_add, state); 951 } else 952 if (*srv->server_name == 0) 953 { 954 smbwrp_special_add(".", state); 955 smbwrp_special_add("..", state); 956 957 cli_NetServerEnum(cli, srv->workgroup, SV_TYPE_ALL, 958 smbwrp_share_add, state); 959 } else 960 if ((strcmp(cli->dev,"IPC") == 0) || *srv->share_name == 0 || (stricmp(srv->share_name,"IPC$") == 0)) 961 { 962 smbwrp_special_add(".", state); 963 smbwrp_special_add("..", state); 964 965 if (net_share_enum_rpc(cli, smbwrp_share_add, state) < 0 && 966 cli_RNetShareEnum(cli,smbwrp_share_add, state) < 0) 967 { 968 return os2cli_errno(cli); 969 } 970 } else 971 if (strncmp(cli->dev,"LPT",3) == 0) 972 { 973 smbwrp_special_add(".", state); 974 smbwrp_special_add("..", state); 975 if (cli_print_queue_state(cli, smbwrp_printjob_add, state) < 0) 976 { 977 return os2cli_errno(cli); 978 } 979 } 980 else 981 { 982 if (list_files(cli, state->mask, aHIDDEN|aSYSTEM|aDIR, 983 smbwrp_dir_add, state) < 0) 984 { 985 return os2cli_errno(cli); 986 } 987 } 988 989 return 0; 990 } 991 992 /***************************************************** 993 a wrapper for chdir() 994 *******************************************************/ 873 if (!srv || !cli || !state || !*state->mask) 874 return maperror(EINVAL); 875 876 debuglocal(1,"Filelist <%s> on master <%s> wgrp <%s> server <%s> share <%s> clidev <%s>\n", state->mask, srv->master, srv->workgroup, srv->server_name, srv->share_name, cli->dev); 877 if (*srv->workgroup == 0 && *srv->server_name == 0) 878 { 879 smbwrp_special_add(".", state); 880 smbwrp_special_add("..", state); 881 cli_NetServerEnum(cli, srv->master, SV_TYPE_DOMAIN_ENUM, 882 smbwrp_share_add, state); 883 } else if (*srv->server_name == 0) 884 { 885 smbwrp_special_add(".", state); 886 smbwrp_special_add("..", state); 887 cli_NetServerEnum(cli, srv->workgroup, SV_TYPE_ALL, 888 smbwrp_share_add, state); 889 } else if ((strcmp(cli->dev,"IPC") == 0) || *srv->share_name == 0 || 890 (stricmp(srv->share_name,"IPC$") == 0)) 891 { 892 smbwrp_special_add(".", state); 893 smbwrp_special_add("..", state); 894 if (net_share_enum_rpc(cli, smbwrp_share_add, state) < 0 && 895 cli_RNetShareEnum(cli,smbwrp_share_add, state) < 0) 896 return os2cli_errno(cli); 897 } else if (strncmp(cli->dev,"LPT",3) == 0) 898 { 899 smbwrp_special_add(".", state); 900 smbwrp_special_add("..", state); 901 if (cli_print_queue_state(cli, smbwrp_printjob_add, state) < 0) 902 return os2cli_errno(cli); 903 } 904 else 905 { 906 if (list_files(cli, state->mask, aHIDDEN|aSYSTEM|aDIR, 907 smbwrp_dir_add, state) < 0) 908 return os2cli_errno(cli); 909 } 910 911 return 0; 912 } 913 914 /* 915 * a wrapper for chdir() 916 */ 995 917 int _System smbwrp_chdir(smbwrp_server *srv, cli_state * cli, char *fname) 996 918 { 997 unsigned short mode = aDIR; 998 smbwrp_fileinfo finfo = {0}; 999 if (!cli || !fname) 1000 { 1001 return maperror(EINVAL); 1002 } 1003 1004 strncpy(finfo.fname, fname, sizeof(finfo.fname) - 1); 1005 if (smbwrp_getattr(srv, cli, &finfo)) 1006 { 1007 return os2cli_errno(cli); 1008 } 1009 1010 if (!(finfo.attr & aDIR)) { 1011 return maperror(ENOTDIR); 1012 } 1013 1014 return 0; 1015 } 1016 1017 1018 /***************************************************** 1019 a wrapper for mkdir() 1020 *******************************************************/ 919 unsigned short mode = aDIR; 920 smbwrp_fileinfo finfo = {0}; 921 if (!cli || !fname) 922 return maperror(EINVAL); 923 924 strncpy(finfo.fname, fname, sizeof(finfo.fname) - 1); 925 if (smbwrp_getattr(srv, cli, &finfo)) 926 return os2cli_errno(cli); 927 928 929 if (!(finfo.attr & aDIR)) 930 return maperror(ENOTDIR); 931 932 933 return 0; 934 } 935 936 937 /* 938 * a wrapper for mkdir() 939 */ 1021 940 int _System smbwrp_mkdir(cli_state * cli, char *fname) 1022 941 { 1023 if (!cli || !fname) 1024 { 1025 return maperror(EINVAL); 1026 } 1027 1028 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) 1029 { 1030 return os2cli_errno(cli); 1031 } 1032 return 0; 1033 } 1034 1035 /***************************************************** 1036 a wrapper for rmdir() 1037 *******************************************************/ 942 if (!cli || !fname) 943 return maperror(EINVAL); 944 945 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) 946 return os2cli_errno(cli); 947 948 return 0; 949 } 950 951 /* 952 * a wrapper for rmdir() 953 */ 1038 954 int _System smbwrp_rmdir(cli_state * cli, char *fname) 1039 955 { 1040 if (!cli || !fname) 1041 { 1042 return maperror(EINVAL); 1043 } 1044 1045 if (!NT_STATUS_IS_OK(cli_rmdir(cli, fname))) 1046 { 1047 return os2cli_errno(cli); 1048 } 1049 return 0; 1050 } 1051 1052 /***************************************************** 1053 set EA for a path 1054 *******************************************************/ 956 if (!cli || !fname) 957 return maperror(EINVAL); 958 959 if (!NT_STATUS_IS_OK(cli_rmdir(cli, fname))) 960 return os2cli_errno(cli); 961 962 return 0; 963 } 964 965 /* 966 * set EA for a path 967 */ 1055 968 int _System smbwrp_setea(cli_state * cli, char *fname, char * name, unsigned char * value, int size) 1056 969 { 1057 if (!cli || !fname || !name) 1058 { 1059 return maperror(EINVAL); 1060 } 1061 if (!NT_STATUS_IS_OK(cli_set_ea_path(cli, fname, name, value, size))) 1062 { 1063 return os2cli_errno(cli); 1064 } 1065 return 0; 1066 } 1067 1068 /***************************************************** 1069 set EA for a file 1070 *******************************************************/ 970 if (!cli || !fname || !name) 971 return maperror(EINVAL); 972 973 if (!NT_STATUS_IS_OK(cli_set_ea_path(cli, fname, name, value, size))) 974 return os2cli_errno(cli); 975 976 return 0; 977 } 978 979 /* 980 * set EA for a file 981 */ 1071 982 int _System smbwrp_fsetea(cli_state * cli, smbwrp_file *file, char * name, unsigned char * value, int size) 1072 983 { 1073 if (!cli || !file || !name) 1074 { 1075 return maperror(EINVAL); 1076 } 1077 if (!NT_STATUS_IS_OK(cli_set_ea_fnum(cli, file->fd, name, value, size))) 1078 { 1079 return os2cli_errno(cli); 1080 } 1081 return 0; 984 if (!cli || !file || !name) 985 return maperror(EINVAL); 986 987 if (!NT_STATUS_IS_OK(cli_set_ea_fnum(cli, file->fd, name, value, size))) 988 return os2cli_errno(cli); 989 990 return 0; 1082 991 } 1083 992 1084 993 1085 994 #pragma pack(1) 1086 typedef struct _FEA /* fea */1087 { 1088 unsigned char fEA; /* flags */ 1089 unsigned char cbName; /* name length not including NULL */ 1090 unsigned short cbValue; /* value length */ 995 typedef struct _FEA 996 { 997 unsigned char fEA; // flags 998 unsigned char cbName; // name length not including NULL 999 unsigned short cbValue; // value length 1091 1000 } FEA; 1092 1001 1093 typedef struct _FEALIST /* feal */1094 { 1095 unsigned long cbList; /* total bytes of structure including full list */ 1096 FEA list[1]; /* variable length FEA structures */ 1002 typedef struct _FEALIST 1003 { 1004 unsigned long cbList; // total bytes of structure including full list 1005 FEA list[1]; // variable length FEA structures 1097 1006 } FEALIST; 1098 1007 #pragma pack() … … 1100 1009 static int unilistea(cli_state * cli, char *fname, void * buffer, unsigned long size) 1101 1010 { 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 } 1154 1155 /* ****************************************************1156 lists EA of a path1157 *******************************************************/1011 int fnum, i; 1012 int gotsize = sizeof(unsigned long); 1013 size_t num_eas; 1014 struct ea_struct *ea_list = NULL; 1015 TALLOC_CTX *mem_ctx; 1016 FEA * p; 1017 FEALIST * pfealist; 1018 char * q; 1019 1020 mem_ctx = talloc_init("%d: ealist", _gettid()); 1021 pfealist = (FEALIST *)buffer; 1022 pfealist->cbList = 0; 1023 1024 if (!NT_STATUS_IS_OK(cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list))) 1025 { 1026 debuglocal(4,"ea_get_file list failed - %s\n", cli_errstr(cli)); 1027 talloc_destroy(mem_ctx); 1028 return os2cli_errno(cli); 1029 } 1030 1031 debuglocal(4,"num_eas = %d\n", num_eas); 1032 1033 // we will count that os/2 max EA size for file is 64kb 1034 p = pfealist->list; 1035 for (i = 0; i < num_eas; i++) 1036 { 1037 int namelen = strlen(ea_list[i].name); 1038 debuglocal(4, "%d Got EA <%s> with namelen %d, size %d. Gross %d. Buf %d\n", i, ea_list[i].name, namelen, ea_list[i].value.length, gotsize, size); 1039 if (namelen > 0xFF || ea_list[i].value.length > 0xFFFF) 1040 { 1041 debuglocal(4, "Skip EA <%s> with namelen %d, size %d\n", ea_list[i].name, namelen, ea_list[i].value.length); 1042 continue; 1043 } 1044 gotsize += sizeof(FEA) + namelen + ea_list[i].value.length + 1; 1045 if (size >= gotsize) 1046 { 1047 p->fEA = 0; 1048 p->cbName = namelen; 1049 p->cbValue = ea_list[i].value.length; 1050 q = (char *)(p + 1); 1051 strncpy(q, ea_list[i].name, namelen + 1); 1052 q += namelen + 1; 1053 memcpy(q, ea_list[i].value.data, ea_list[i].value.length); 1054 p = (FEA *)(q + ea_list[i].value.length); 1055 } 1056 } 1057 pfealist->cbList = gotsize; 1058 debuglocal(4,"ret size = %d\n", gotsize); 1059 1060 talloc_destroy(mem_ctx); 1061 return 0; 1062 } 1063 1064 /* 1065 * lists EA of a path 1066 */ 1158 1067 int _System smbwrp_listea(cli_state * cli, char *fname, void * buffer, unsigned long size) 1159 1068 { 1160 if (!cli || !fname || !buffer) 1161 { 1162 return maperror(EINVAL); 1163 } 1164 1165 debuglocal(4,"EALIst for <%s>\n", fname); 1166 return unilistea(cli, fname, buffer, size); 1167 } 1168 1169 /***************************************************** 1170 lists EA of a file 1171 *******************************************************/ 1069 if (!cli || !fname || !buffer) 1070 return maperror(EINVAL); 1071 1072 debuglocal(4,"EALIst for <%s>\n", fname); 1073 return unilistea(cli, fname, buffer, size); 1074 } 1075 1076 /* 1077 * lists EA of a file 1078 */ 1172 1079 int _System smbwrp_flistea(cli_state * cli, smbwrp_file *file, void * buffer, unsigned long size) 1173 1080 { 1174 if (!cli || !file || !buffer) 1175 { 1176 return maperror(EINVAL); 1177 } 1178 1179 debuglocal(4,"FEALIst for <%s>\n", file->fname); 1180 return unilistea(cli, file->fname, buffer, size); 1181 } 1182 1183 /**************************************************************************** 1184 Check the space on a device. 1185 ****************************************************************************/ 1081 if (!cli || !file || !buffer) 1082 return maperror(EINVAL); 1083 1084 debuglocal(4,"FEALIst for <%s>\n", file->fname); 1085 return unilistea(cli, file->fname, buffer, size); 1086 } 1087 1088 /* 1089 * Check the space on a device. 1090 */ 1186 1091 int _System smbwrp_dskattr(cli_state * cli, FSALLOCATE *pfsa) 1187 1092 { 1188 int total, bsize, avail; 1189 1190 if (!cli || !pfsa) 1191 { 1192 return maperror(EINVAL); 1193 } 1194 1195 if (!NT_STATUS_IS_OK(cli_dskattr(cli, &bsize, &total, &avail))) 1196 { 1197 debuglocal(4,"Error in dskattr: %s\n",cli_errstr(cli)); 1198 return os2cli_errno(cli); 1199 } 1200 1201 debuglocal(4,"\n\t\t%d blocks of size %d. %d blocks available\n", 1202 total, bsize, avail); 1203 1204 // YD currently Samba return it in MB! 1205 pfsa->cSectorUnit = 1; 1206 if (bsize >= 65536) 1207 { 1208 pfsa->cUnit = total*1024; 1209 pfsa->cUnitAvail = avail*1024; 1210 pfsa->cbSector = bsize/1024; 1211 } 1212 else 1213 { 1214 pfsa->cUnit = total; 1215 pfsa->cUnitAvail = avail; 1216 pfsa->cbSector = bsize; 1217 } 1218 1219 return 0; 1220 } 1221 1093 int total, bsize, avail; 1094 1095 if (!cli || !pfsa) 1096 return maperror(EINVAL); 1097 1098 if (!NT_STATUS_IS_OK(cli_dskattr(cli, &bsize, &total, &avail))) 1099 { 1100 debuglocal(4,"Error in dskattr: %s\n",cli_errstr(cli)); 1101 return os2cli_errno(cli); 1102 } 1103 1104 debuglocal(4,"\n\t\t%d blocks of size %d. %d blocks available\n", 1105 total, bsize, avail); 1106 1107 // YD currently Samba return it in MB! 1108 pfsa->cSectorUnit = 1; 1109 if (bsize >= 65536) 1110 { 1111 pfsa->cUnit = total*1024; 1112 pfsa->cUnitAvail = avail*1024; 1113 pfsa->cbSector = bsize/1024; 1114 } 1115 else 1116 { 1117 pfsa->cUnit = total; 1118 pfsa->cUnitAvail = avail; 1119 pfsa->cbSector = bsize; 1120 } 1121 1122 return 0; 1123 } -
trunk/client/src/smbwrp.h
r957 r959 74 74 typedef struct smbwrp_server 75 75 { 76 77 78 79 80 81 82 83 76 char server_name[256]; 77 char share_name[256]; 78 char workgroup[256]; 79 char username[256]; 80 char password[256]; 81 char master[256]; 82 int ifmastergroup; 83 int no_pathinfo2; 84 84 } smbwrp_server; 85 85 86 86 typedef struct smbwrp_file 87 87 { 88 89 90 91 92 93 94 95 96 97 98 99 100 88 int fd; 89 unsigned long long offset; 90 int openmode; 91 int openattr; 92 int denymode; 93 unsigned long mtime; 94 unsigned long ctime; 95 int updatetime; 96 // 0 = time is not updated upon file close 97 // 1 = modified time is updated to current time 98 // 2 = create and modified time are updated according local file 99 char fullname[261]; 100 char fname[261]; 101 101 } smbwrp_file; 102 102 103 103 typedef struct smbwrp_fileinfo 104 104 { 105 106 107 108 109 110 111 105 unsigned long long size; 106 unsigned long attr; 107 unsigned long ctime; 108 unsigned long mtime; 109 unsigned long atime; 110 int easize; 111 char fname[261]; 112 112 } smbwrp_fileinfo; 113 113 114 114 typedef struct smbwrp_fileseek 115 115 { 116 117 118 116 int whence; 117 long offset; 118 unsigned long result; 119 119 } smbwrp_fileseek; 120 120 … … 123 123 typedef struct _FSALLOCATE /* fsalloc */ 124 124 { 125 126 127 128 129 125 unsigned long idFileSystem; 126 unsigned long cSectorUnit; 127 unsigned long cUnit; 128 unsigned long cUnitAvail; 129 unsigned short cbSector; 130 130 } FSALLOCATE; 131 131 #endif … … 135 135 typedef struct _Resource 136 136 { 137 int rootlevel; 138 smbwrp_server srv; 139 char logfile[_MAX_PATH + 1]; 140 char loglevel; 141 int easupport; 142 int krb5support; 137 int rootlevel; 138 smbwrp_server srv; 139 int easupport; 140 int krb5support; 143 141 int cachetimeout; 144 142 int cachedepth; 145 struct DirectoryCache *pdc; 143 int loglevel; 144 struct DirectoryCache *pdc; 146 145 } Resource; 147 146 148 147 typedef struct _Connection 149 148 { 150 151 152 149 Resource *pRes; 150 cli_state* cli; 151 smbwrp_file file; 153 152 } Connection; 154 153 … … 156 155 typedef struct filelist_state 157 156 { 158 159 160 161 162 163 164 165 166 167 168 169 170 157 unsigned long pipe; 158 char * data; 159 int datalen; 160 int bufferlen; 161 void ( * _System add_dir_entry)(void * st); 162 char mask[ _MAX_PATH]; 163 char dir[ _MAX_PATH]; 164 char dir_mask[ _MAX_PATH]; 165 smbwrp_fileinfo finfo; 166 Connection* pConn; 167 void *plist; 168 unsigned long ulAttribute; 169 const char *fullpath; 171 170 } filelist_state; 172 171 -
trunk/client/src/util.c
r957 r959 26 26 #include <stdlib.h> 27 27 #include <string.h> 28 #include <stdio.h> 28 29 29 30 #include "smbwrp.h" … … 32 33 int maperror(int rc) 33 34 { 34 switch (rc) 35 { 36 case 0 : return NO_ERROR ; /* NO_ERROR */ 37 case 1 : return ERROR_ACCESS_DENIED ; /* EPERM - Operation not permitted */ 38 case 2 : return ERROR_FILE_NOT_FOUND ; /* ENOENT - No such file or directory */ 39 case 3 : return ERROR_PID_MISMATCH ; /* ESRCH - No such process */ 40 case 4 : return ERROR_INTERRUPT ; /* EINTR - Interrupted system call */ 41 case 5 : return ERROR_READ_FAULT ; /* EIO - I/O error */ 42 case 6 : return ERROR_BAD_UNIT ; /* ENXIO - No such device or address */ 43 case 7 : return ERROR_INVALID_DATA ; /* E2BIG - Arguments or environment too big */ 44 case 8 : return ERROR_BAD_EXE_FORMAT ; /* ENOEXEC - Invalid executable file format */ 45 case 9 : return ERROR_INVALID_HANDLE ; /* EBADF - Bad file number */ 46 case 10 : return ERROR_NO_CHILD_PROCESS ; /* ECHILD - No child processes */ 47 case 11 : return ERROR_BUSY ; /* EAGAIN - Resource temporarily unavailable */ 48 case 12 : return ERROR_NOT_ENOUGH_MEMORY ; /* ENOMEM - Not enough memory */ 49 case 13 : return ERROR_ACCESS_DENIED ; /* EACCES - Permission denied */ 50 case 14 : return ERROR_INVALID_ADDRESS ; /* EFAULT - Bad address */ 51 case 15 : return ERROR_NOT_LOCKED ; /* ENOLCK - No locks available */ 52 case 16 : return ERROR_BUSY ; /* EBUSY - Resource busy */ 53 case 17 : return ERROR_FILE_EXISTS ; /* EEXIST - File exists */ 54 case 18 : return ERROR_NOT_SAME_DEVICE ; /* EXDEV - Cross-device link */ 55 case 19 : return ERROR_REM_NOT_LIST ; /* ENODEV - No such device */ 56 case 20 : return ERROR_PATH_NOT_FOUND ; /* ENOTDIR - Not a directory */ 57 case 21 : return ERROR_DIRECTORY ; /* EISDIR - Is a directory */ 58 case 22 : return ERROR_INVALID_PARAMETER ; /* EINVAL - Invalid argument */ 59 case 23 : return ERROR_TOO_MANY_OPEN_FILES ; /* ENFILE - Too many open files in system */ 60 case 24 : return ERROR_TOO_MANY_OPENS ; /* EMFILE - Too many open files */ 61 case 25 : return ERROR_MOD_NOT_FOUND ; /* ENOTTY - Inappropriate ioctl */ 62 case 26 : return ERROR_LOCK_VIOLATION ; /* EDEADLK - Resource deadlock avoided */ 63 case 27 : return ERROR_TRANSFER_TOO_LONG ; /* EFBIG - File too large */ 64 case 28 : return ERROR_DISK_FULL ; /* ENOSPC - Disk full */ 65 case 29 : return ERROR_SEEK ; /* ESPIPE - Invalid seek */ 66 case 30 : return ERROR_WRITE_PROTECT ; /* EROFS - Read-only file system */ 67 case 31 : return ERROR_TOO_MANY_OPEN_FILES ; /* EMLINK - Too many links */ 68 case 32 : return ERROR_BROKEN_PIPE ; /* EPIPE - Broken pipe */ 69 case 33 : return ERROR_INVALID_LEVEL ; /* EDOM - Domain error */ 70 case 34 : return ERROR_FILENAME_EXCED_RANGE ; /* ERANGE - Result too large */ 71 case 35 : return ERROR_DIR_NOT_EMPTY ; /* ENOTEMPTY - Directory not empty */ 72 case 36 : return ERROR_BUSY_DRIVE ; /* EINPROGRESS - Operation now in progress */ 73 case 37 : return ERROR_INVALID_FUNCTION ; /* ENOSYS - Function not implemented */ 74 case 38 : return ERROR_FILENAME_EXCED_RANGE ; /* ENAMETOOLONG - File name too long */ 75 case 39 : return ERROR_KBD_FOCUS_REQUIRED ; /* EDESTADDRREQ - Destination address required */ 76 case 40 : return ERROR_TRANSFER_TOO_LONG ; /* EMSGSIZE - Message too long */ 77 case 48 : return ERROR_NETWORK_BUSY ; /* EADDRINUSE - Address already in use */ 78 case 49 : return ERROR_INFO_NOT_AVAIL ; /* EADDRNOTAVAIL - Can't assigned requested address */ 79 case 50 : return ERROR_NETWORK_ACCESS_DENIED ; /* ENETDOWN - Network is down */ 80 case 51 : return ERROR_NETWORK_ACCESS_DENIED ; /* ENETUNREACH - Network is unreachable */ 81 case 52 : return ERROR_NETWORK_ACCESS_DENIED ; /* ENETRESET - Network dropped connection on reset */ 82 case 53 : return ERROR_NETWORK_ACCESS_DENIED ; /* ECONNABORTED - Software caused connection abort */ 83 case 54 : return ERROR_NETWORK_ACCESS_DENIED ; /* ECONNRESET - Connection reset by peer */ 84 case 55 : return ERROR_BUFFER_OVERFLOW ; /* ENOBUFS - No buffer space available */ 85 case 56 : return ERROR_PIPE_BUSY ; /* EISCONN - Socket is already connected */ 86 case 57 : return ERROR_REM_NOT_LIST ; /* ENOTCONN - Socket is not connected */ 87 case 58 : return ERROR_ALREADY_SHUTDOWN ; /* ESHUTDOWN - Can't send after socket shutdown */ 88 case 60 : return ERROR_TIMEOUT ; /* ETIMEDOUT - Connection timed out */ 89 case 61 : return ERROR_NETWORK_ACCESS_DENIED ; /* ECONNREFUSED - Connection refused */ 90 case 63 : return ERROR_INVALID_BLOCK ; /* ENOTSOCK - Socket operation on non-socket */ 91 case 64 : return ERROR_BAD_FORMAT ; /* EHOSTDOWN - Host is down */ 92 case 65 : return ERROR_BAD_NETPATH ; /* EHOSTUNREACH - No route to host */ 93 case 66 : return ERROR_BUSY_DRIVE ; /* EALREADY - Operation already in progress */ 94 } 35 switch (rc) 36 { 37 case 0 : // NO_ERROR 38 return NO_ERROR; 39 case 1 : // EPERM - Operation nt permitted 40 case 13 : // EACCES - Permission denied 41 return ERROR_ACCESS_DENIED; 42 case 2 : // ENOENT - No such file or directory 43 return ERROR_FILE_NOT_FOUND; 44 case 3 : // ESRCH - No such process 45 return ERROR_PID_MISMATCH; 46 case 4 : // EINTR - Interrupted system call 47 return ERROR_INTERRUPT; 48 case 5 : // EIO - I/O error 49 return ERROR_READ_FAULT; 50 case 6 : // ENXIO - No such device or address 51 return ERROR_BAD_UNIT; 52 case 7 : // E2BIG - Arguments or environment too big 53 return ERROR_INVALID_DATA; 54 case 8 : // ENOEXEC - Invalid executable file format 55 return ERROR_BAD_EXE_FORMAT; 56 case 9 : // EBADF - Bad file number 57 return ERROR_INVALID_HANDLE; 58 case 10 : // ECHILD - No child processes 59 return ERROR_NO_CHILD_PROCESS; 60 case 11 : // EAGAIN - Resource temporarily unavailable 61 case 16 : // EBUSY - Resource busy 62 return ERROR_BUSY; 63 case 12 : // ENOMEM - Not enough memory 64 return ERROR_NOT_ENOUGH_MEMORY; 65 case 14 : // EFAULT - Bad address 66 return ERROR_INVALID_ADDRESS; 67 case 15 : // ENOLCK - No locks available 68 return ERROR_NOT_LOCKED; 69 case 17 : // EEXIST - File exists 70 return ERROR_FILE_EXISTS; 71 case 18 : // EXDEV - Cross-device link 72 return ERROR_NOT_SAME_DEVICE; 73 case 19 : // ENODEV - No such device 74 case 57 : // ENOTCONN - Socket is not connected 75 return ERROR_REM_NOT_LIST; 76 case 20 : // ENOTDIR - Not a directory 77 return ERROR_PATH_NOT_FOUND; 78 case 21 : // EISDIR - Is a directory 79 return ERROR_DIRECTORY; 80 case 22 : // EINVAL - Invalid argument 81 return ERROR_INVALID_PARAMETER; 82 case 23 : // ENFILE - Too many open files in system 83 case 31 : // EMLINK - Too many links 84 return ERROR_TOO_MANY_OPEN_FILES; 85 case 24 : // EMFILE - Too many open files 86 return ERROR_TOO_MANY_OPENS; 87 case 25 : // ENOTTY - Inappropriate ioctl 88 return ERROR_MOD_NOT_FOUND; 89 case 26 : // EDEADLK - Resource deadlock avoided 90 return ERROR_LOCK_VIOLATION; 91 case 27 : // EFBIG - File too large 92 case 40 : // EMSGSIZE - Message too long 93 return ERROR_TRANSFER_TOO_LONG; 94 case 28 : // ENOSPC - Disk full 95 return ERROR_DISK_FULL; 96 case 29 : // ESPIPE - Invalid seek 97 return ERROR_SEEK; 98 case 30 : // EROFS - Read-only file system 99 return ERROR_WRITE_PROTECT; 100 case 32 : // EPIPE - Broken pipe 101 return ERROR_BROKEN_PIPE; 102 case 33 : // EDOM - Domain error 103 return ERROR_INVALID_LEVEL; 104 case 34 : // ENAMETOOLONG - File name too long 105 case 38 : // ERANGE - Result too large 106 return ERROR_FILENAME_EXCED_RANGE; 107 case 35 : // ENOTEMPTY - Directory not empty 108 return ERROR_DIR_NOT_EMPTY; 109 case 36 : // EINPROGRESS - Operation now in progress 110 case 66 : // EALREADY - Operation already in progress 111 return ERROR_BUSY_DRIVE; 112 case 37 : // ENOSYS - Function not implemented 113 return ERROR_INVALID_FUNCTION; 114 case 39 : // EDESTADDRREQ - Destination address required 115 return ERROR_KBD_FOCUS_REQUIRED; 116 case 48 : // EADDRINUSE - Address already in use 117 return ERROR_NETWORK_BUSY; 118 case 49 : // EADDRNOTAVAIL - Can't assigned requested address 119 return ERROR_INFO_NOT_AVAIL; 120 case 50 : // ENETDOWN - Network is down 121 case 51 : // ENETUNREACH - Network is unreachable 122 case 52 : // ENETRESET - Network dropped connection on reset 123 case 53 : // ECONNABORTED - Software caused connection abort 124 case 54 : // ECONNRESET - Connection reset by peer 125 return ERROR_NETWORK_ACCESS_DENIED; 126 case 55 : // ENOBUFS - No buffer space available 127 return ERROR_BUFFER_OVERFLOW; 128 case 56 : // EISCONN - Socket is already connected 129 return ERROR_PIPE_BUSY; 130 case 58 : // ESHUTDOWN - Can't send after socket shutdown 131 return ERROR_ALREADY_SHUTDOWN; 132 case 60 : // ETIMEDOUT - Connection timed out 133 return ERROR_TIMEOUT; 134 case 61 : // ECONNREFUSED - Connection refused 135 return ERROR_NETWORK_ACCESS_DENIED; 136 case 63 : // ENOTSOCK - Socket operation on non-socket 137 return ERROR_INVALID_BLOCK; 138 case 64 : // EHOSTDOWN - Host is down 139 return ERROR_BAD_FORMAT; 140 case 65 : // EHOSTUNREACH - No route to host 141 return ERROR_BAD_NETPATH; 142 } 95 143 // debug_printf( "Unhandled return code %d\n"); 96 144 return rc + 40000; 97 145 } 98 146 99 147 char * getlastslash(char * path) 100 148 { 101 char * p; 102 if (!path) 103 { 104 return NULL; 105 } 106 for (p = path + strlen(path) - 1; p >= path; p--) 107 { 108 if (*p == '\\' || *p == '/') 109 { 110 return p; 111 } 112 } 113 return NULL; 149 char * p; 150 if (!path) 151 return NULL; 152 153 for (p = path + strlen(path) - 1; p >= path; p--) 154 { 155 if (*p == '\\' || *p == '/') 156 return p; 157 } 158 return NULL; 114 159 } 115
Note:
See TracChangeset
for help on using the changeset viewer.