Ignore:
Timestamp:
Aug 16, 2016, 5:35:07 PM (9 years ago)
Author:
Silvan Scherrer
Message:

samba client: remove tabs in source and beautify it completely

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/client/src/ndpsmb.c

    r957 r959  
    3232#include "util.h"
    3333
    34 #define debug_printf(...) debuglocal(9, __VA_ARGS__)
    35 
    3634// -------------------------------------------------------------
    3735
     
    4341void fsphUnixTimeToDosDate( time_t time, FDATE* fdate, FTIME *ftime)
    4442{
    45         struct tm* gmt = localtime( &time);
     43        struct tm* gmt = localtime( &time);
    4644#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        }
    5251#endif
    53         fdate->day  = gmt->tm_mday;
    54         fdate->month  = gmt->tm_mon+1;
    55         fdate->year = gmt->tm_year + 1900 - 1980;
    56         ftime->twosecs = gmt->tm_sec/2;
    57         ftime->minutes = gmt->tm_min;
    58         ftime->hours = gmt->tm_hour;
     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;
    5958}
    6059
    6160void fsphDosDateToUnixTime( FDATE fdate, FTIME ftime, ULONG* time)
    6261{
    63         struct tm gmtime = { 0 };
    64 
    65         debug_printf( "fsphDosDateToUnixTime time %02d:%02d:%02d\n", ftime.hours, ftime.minutes, ftime.twosecs*2);
    66         gmtime.tm_mday = fdate.day;
    67         gmtime.tm_mon = fdate.month-1;
    68         gmtime.tm_year = fdate.year + 1980 - 1900;
    69         gmtime.tm_sec = ftime.twosecs*2;
    70         gmtime.tm_min = ftime.minutes;
    71         gmtime.tm_hour = ftime.hours;
    72         gmtime.tm_isdst = -1; // force libc to check dst saving
    73 
    74         *time = mktime( &gmtime);
    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));
    7675#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));
    8484#endif
    8585}
     
    9090const char *NdpTypes[] =
    9191{
    92         "SMBFS",
    93         NULL
     92        "SMBFS",
     93        NULL
    9494}
    9595;
     
    100100static const NDPROPERTYINFO smbProperties[] =
    101101{
    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}
     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}
    114114};
    115115
     
    118118const NDPROPERTYINFO *NdpPropertiesInfo[] =
    119119{
    120         smbProperties
     120        smbProperties
    121121};
    122122
     
    130130static int lockInit (void)
    131131{
    132         return ph->fsphCreateMutex (&mutex);
     132        return ph->fsphCreateMutex (&mutex);
    133133}
    134134
    135135static void lockClose (void)
    136136{
    137         ph->fsphCloseMutex (mutex);
     137        ph->fsphCloseMutex (mutex);
    138138}
    139139
    140140static int lockRequest (void)
    141141{
    142         return ph->fsphRequestMutex (mutex, SEM_INDEFINITE_WAIT);
     142        return ph->fsphRequestMutex (mutex, SEM_INDEFINITE_WAIT);
    143143}
    144144
    145145static void lockRelease (void)
    146146{
    147         ph->fsphReleaseMutex (mutex);
     147        ph->fsphReleaseMutex (mutex);
    148148}
    149149
    150150#if LIBSMB_THREAD_SAFE==0
    151151
    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;           \
    156156} while (0)
    157157
    158 #define LEAVE() do {    \
    159         lockRelease();  \
     158#define LEAVE() do {   \
     159        lockRelease(); \
    160160} while (0)
    161161
     
    167167int helperEASet (cli_state *cli, FEALIST *pFEAList, char *path)
    168168{
    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;
    196193}
    197194
    198195int APIENTRY NdpPluginLoad (PLUGINHELPERTABLE2L *pPHT)
    199196{
    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;
    219206}
    220207
     
    222209int APIENTRY NdpPluginFree (void)
    223210{
    224         debugDelete();
    225         lockClose();
    226         return NO_ERROR;
     211        debugDelete();
     212        lockClose();
     213        return NO_ERROR;
    227214}
    228215
     
    230217void getfindinfo(Connection * pConn, FILEFINDBUF3 * stat, smbwrp_fileinfo * finfo)
    231218{
    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;
    255240}
    256241
    257242int getfindinfoL(Connection * pConn, void * plist, smbwrp_fileinfo * finfo, ULONG ulAttribute, char * mask)
    258243{
    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;
    291270}
    292271
    293272static unsigned char fromhex (char c)
    294273{
    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;
    311284}
    312285
    313286static char tohex (unsigned char b)
    314287{
    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);
    323294}
    324295
    325296static void decryptPassword (const char *pszCrypt, char *pszPlain)
    326297{
    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;
    337309}
    338310
    339311static void encryptPassword (const char *pszPlain, char *pszCrypt)
    340312{
    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;
    353326}
    354327
     
    358331int initResource (Resource *pRes, NDPROPERTYHANDLE properties)
    359332{
    360         int rc = NO_ERROR;
    361         unsigned long t;
    362         const CHAR * q = NULL;
    363         int defaultPassword = 1;
    364 
    365         pRes->rootlevel = 0;
    366         pRes->easupport = 1;
     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;
    367340#ifdef HAVE_KRB5_H
    368         pRes->krb5support = 1;
     341        pRes->krb5support = 1;
    369342#else
    370         pRes->krb5support = 0;
     343        pRes->krb5support = 0;
    371344#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;
    511460}
    512461
    513462int iftestpath(char * path)
    514463{
    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;
    529475}
    530476
    531477int pathparser(Resource *pRes, Connection * pConn, char * path, char * result)
    532478{
    533         int rootlevel;
    534         int rc = NO_ERROR;
    535         if (!pRes || !path || !result)
    536         {
    537                 return ERROR_INVALID_PARAMETER;
    538         }
    539         // handle special case when someone wants to test support of LFN or smth similar
    540         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                                 p = path + strlen(path);
    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}
    636582
    637583/* check if the requested resource is available */
    638584static int checkMountResource( Resource* pRes)
    639585{
    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;
    681624}
    682625
    683626int APIENTRY NdpMountResource (HRESOURCE *presource, int type, NDPROPERTYHANDLE properties)
    684627{
    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}
    731672
    732673int APIENTRY NdpFreeResource (HRESOURCE resource)
    733674{
    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}
    745684
    746685int APIENTRY NdpRsrcCompare (HRESOURCE resource, HRESOURCE resource2)
    747686{
    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;
    765703}
    766704
    767705int APIENTRY NdpRsrcUpdate (HRESOURCE resource, HRESOURCE resource2)
    768706{
    769         // do nothing
    770         debuglocal(9,"NdpRsrcUpdate %d\n", NO_ERROR);
    771         return NO_ERROR;
     707        // do nothing
     708        debuglocal(9, "NdpRsrcUpdate %d\n", NO_ERROR);
     709        return NO_ERROR;
    772710}
    773711
    774712int APIENTRY NdpRsrcQueryInfo (HRESOURCE resource, ULONG *pulFlags, void *pdata, ULONG insize, ULONG *poutlen)
    775713{
    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;
    814743}
    815744
    816745int APIENTRY NdpRsrcQueryFSAttach (HRESOURCE resource, void *pdata, ULONG insize, ULONG *poutlen)
    817746{
    818         ULONG ulDummy = 0;
    819         /* just return the resource info string */
    820         return NdpRsrcQueryInfo (resource, &ulDummy, pdata, insize, poutlen);
     747        ULONG ulDummy = 0;
     748        // just return the resource info string
     749        return NdpRsrcQueryInfo (resource, &ulDummy, pdata, insize, poutlen);
    821750}
    822751
    823752int APIENTRY NdpRsrcQueryFSAllocate (HRESOURCE resource, NDFSALLOCATE *pfsa)
    824753{
    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}
    879806
    880807int APIENTRY NdpCreateConnection (HRESOURCE resource, HCONNECTION *pconn)
    881808{
    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}
    922848
    923849int APIENTRY NdpFreeConnection (HCONNECTION conn)
    924850{
    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}
    947872
    948873/*
     
    965890int APIENTRY NdpQueryPathInfo (HCONNECTION conn, void *plist, char *szPath)
    966891{
    967         Connection *pConn = (Connection *)conn;
    968         Resource *pRes = pConn->pRes;
    969         smbwrp_fileinfo finfo;
    970         int rc = 0;
    971         int rcCon = 0;
    972         unsigned long action;
    973         char path[CCHMAXPATH+1] = {0};
    974 
    975         ENTER();
    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);
    978903       
    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}
    10901005
    10911006int APIENTRY NdpFindStart (HCONNECTION conn, void *plist, NDFILEINFOL *pfiparent, char *szPath, ULONG ulAttribute)
    10921007{
    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;
    11831101}
    11841102
    11851103int APIENTRY NdpDeletePathInfo (HRESOURCE resource, NDFILEINFOL *pfi)
    11861104{
    1187 //      debuglocal(9,"NdpDeletePathInfo %d\n", 0);
    1188         return NO_ERROR;
     1105        debuglocal(9, "NdpDeletePathInfo %d\n", 0);
     1106        return NO_ERROR;
    11891107}
    11901108
    11911109int APIENTRY NdpRefresh (HCONNECTION conn, char *path, int tree)
    11921110{
    1193         debuglocal(9,"NdpRefresh <%s> %d\n", path, 0);
    1194         return NO_ERROR;
     1111        debuglocal(9, "NdpRefresh <%s> %d\n", path, 0);
     1112        return NO_ERROR;
    11951113}
    11961114
    11971115int APIENTRY NdpDiscardResourceData (HRESOURCE resource, NDDATABUF *pdatabuf)
    11981116{
    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         return NO_ERROR;
     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;
    12071125}
    12081126
    12091127int APIENTRY NdpSetPathInfo (HCONNECTION conn, NDFILEINFOL *pfi, char *szPathName)
    12101128{
    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;
    12421159}
    12431160
    12441161int buildFEALIST(FEALIST *pFEASrc, GEALIST *pGEAList, FEALIST *pFEAList)
    12451162{
    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;
    13011223}
    13021224
    13031225int APIENTRY NdpEAQuery (HCONNECTION conn, GEALIST *pGEAList, NDFILEINFOL *pfi, FEALIST *pFEAList)
    13041226{
    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;
    13781291}
    13791292
    13801293int APIENTRY NdpEASet (HCONNECTION conn, FEALIST *pFEAList, NDFILEINFOL *pfi)
    13811294{
    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;
    14141324}
    14151325
    14161326int APIENTRY NdpEASize (HCONNECTION conn, NDFILEINFOL *pfi, ULONG *pulEASize)
    14171327{
    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;
    14971400}
    14981401
    14991402int APIENTRY NdpSetCurrentDir (HCONNECTION conn, NDFILEINFOL *pfi, char *szPath)
    15001403{
    1501         Connection *pConn = (Connection *)conn;
    1502         Resource *pRes = pConn->pRes;
    1503         int rc = 0;
    1504         unsigned long action;
    1505         char path[CCHMAXPATH+1] = {0};
     1404        Connection *pConn = (Connection *)conn;
     1405        Resource *pRes = pConn->pRes;
     1406        int rc = 0;
     1407        unsigned long action;
     1408        char path[CCHMAXPATH+1] = {0};
    15061409       
    1507         debuglocal(9,"NdpSetCurrentDir in [%p]\n", pConn);
    1508 
    1509         ENTER();
    1510 
    1511         do {
    1512                 rc = pathparser(pRes, pConn, szPath, path);
    1513                 if (rc)
    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         LEAVE();
    1522         return rc;
     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;
    15231426}
    15241427
    15251428int APIENTRY NdpCopy (HCONNECTION conn, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, ULONG ulOption)
    15261429{
    1527         debuglocal(9,"NdpCopy <%s> -> <%s> %d\n", szSrc, szDst, ERROR_CANNOT_COPY);
    1528         return ERROR_CANNOT_COPY;
     1430        debuglocal(9, "NdpCopy <%s> -> <%s> %d\n", szSrc, szDst, ERROR_CANNOT_COPY);
     1431        return ERROR_CANNOT_COPY;
    15291432}
    15301433
    15311434int APIENTRY NdpCopy2 (HCONNECTION conn, HRESOURCE resDst, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, ULONG ulOption)
    15321435{
    1533         debuglocal(9,"NdpCopy2 <%s> -> <%s> %d\n", szSrc, szDst, ERROR_CANNOT_COPY);
    1534         return ERROR_CANNOT_COPY;
     1436        debuglocal(9, "NdpCopy2 <%s> -> <%s> %d\n", szSrc, szDst, ERROR_CANNOT_COPY);
     1437        return ERROR_CANNOT_COPY;
    15351438}
    15361439
    15371440int APIENTRY NdpForceDelete (HCONNECTION conn, NDFILEINFOL *pfi, char *szFile)
    15381441{
    1539         Connection *pConn = (Connection *)conn;
    1540         Resource *pRes = pConn->pRes;
    1541         int rc = 0;
    1542         unsigned long action;
    1543         char path[CCHMAXPATH+1] = {0};
    1544 
    1545         ENTER();
    1546 
    1547         debuglocal(9,"NdpForceDelete in [%p]\n", pConn);
    1548 
    1549         dircache_invalidate(szFile, pRes->pdc, 1);
    1550 
    1551         do {
    1552                 rc = pathparser(pRes, pConn, szFile, path);
    1553                 if (rc)
    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         LEAVE();
    1562         return rc;
     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;
    15631466}
    15641467
    15651468int APIENTRY NdpCreateDir (HCONNECTION conn, NDFILEINFOL *pfiparent, char *szDirName, FEALIST *pFEAList)
    15661469{
    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;
    15981499}
    15991500
    16001501int APIENTRY NdpDeleteDir (HCONNECTION conn, NDFILEINFOL *pfi, char *szDir)
    16011502{
    1602         Connection *pConn = (Connection *)conn;
    1603         Resource *pRes = pConn->pRes;
    1604         int rc = 0;
    1605         unsigned long action;
    1606         char path[CCHMAXPATH+1] = {0};
    1607 
    1608         ENTER();
    1609 
    1610         debuglocal(9,"NdpDeleteDir in [%p]\n", pConn);
    1611 
    1612         dircache_invalidate(szDir, pRes->pdc, 1);
    1613 
    1614         do {
    1615                 rc = pathparser(pRes, pConn, szDir, path);
    1616                 if (rc)
    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         LEAVE();
    1625         return rc;
     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;
    16261527}
    16271528
    16281529int APIENTRY NdpMove (HCONNECTION conn, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc)
    16291530{
    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;
    16701574}
    16711575
    16721576int APIENTRY NdpMove2 (HCONNECTION conn, HRESOURCE resDst, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc)
    16731577{
    1674         debuglocal(9,"NdpMove2 <%s> -> <%s> %d\n", szSrc, szDst, ERROR_WRITE_PROTECT);
    1675         return ERROR_WRITE_PROTECT;
     1578        debuglocal(9, "NdpMove2 <%s> -> <%s> %d\n", szSrc, szDst, ERROR_WRITE_PROTECT);
     1579        return ERROR_WRITE_PROTECT;
    16761580}
    16771581
     
    16791583int APIENTRY NdpChangeCase (HCONNECTION conn, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, char *szNewName, ULONG ulNameLen)
    16801584{
    1681         return NdpMove (conn, pfiSrc, szDst, pfiSrc, szSrc);
     1585        return NdpMove (conn, pfiSrc, szDst, pfiSrc, szSrc);
    16821586}
    16831587
    16841588int APIENTRY NdpRename (HCONNECTION conn, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, char *szNewName, ULONG ulNameLen)
    16851589{
    1686         return NdpMove (conn, pfiSrc, szDst, pfiSrc, szSrc);
     1590        return NdpMove (conn, pfiSrc, szDst, pfiSrc, szSrc);
    16871591}
    16881592
    16891593int smbopen(Connection *pConn, char *szFileName, int flags, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
    16901594{
    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;
    17401651}
    17411652
    17421653int APIENTRY NdpOpenReplace (HCONNECTION conn, NDFILEINFOL *pfi, NDFILEHANDLE *phandle, char *szFileName, ULONG ulSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
    17431654{
    1744         return smbopen((Connection *)conn, szFileName, O_TRUNC, ulOpenMode, ulAttribute, pFEAList);
     1655        return smbopen((Connection *)conn, szFileName, O_TRUNC, ulOpenMode, ulAttribute, pFEAList);
    17451656}
    17461657
    17471658int APIENTRY NdpOpenReplaceL(HCONNECTION conn, NDFILEINFO *pfi, NDFILEHANDLE *phandle, char *szFileName, LONGLONG llSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
    17481659{
    1749         return smbopen((Connection *)conn, szFileName, O_TRUNC, ulOpenMode, ulAttribute, pFEAList);
     1660        return smbopen((Connection *)conn, szFileName, O_TRUNC, ulOpenMode, ulAttribute, pFEAList);
    17501661}
    17511662
    17521663int APIENTRY NdpOpenCreate (HCONNECTION conn, NDFILEINFOL *pfiparent, NDFILEHANDLE *phandle, char *szFileName, ULONG ulSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
    17531664{
    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);
    17561666}
    17571667
    17581668int APIENTRY NdpOpenCreateL(HCONNECTION conn, NDFILEINFO *pfiparent, NDFILEHANDLE *phandle, char *szFileName, LONGLONG llSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
    17591669{
    1760         return smbopen((Connection *)conn, szFileName, O_CREAT | O_EXCL, ulOpenMode, ulAttribute, pFEAList);
     1670        return smbopen((Connection *)conn, szFileName, O_CREAT | O_EXCL, ulOpenMode, ulAttribute, pFEAList);
    17611671}
    17621672
    17631673int APIENTRY NdpOpenExisting (HCONNECTION conn, NDFILEINFOL *pfi, NDFILEHANDLE *phandle, char *szFileName, ULONG ulOpenMode, USHORT *pfNeedEA)
    17641674{
    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);
    17671678}
    17681679
    17691680int APIENTRY NdpSetFileAttribute (HCONNECTION conn, NDFILEINFOL *pfi, char *szFileName, USHORT usAttr)
    17701681{
    1771         Connection *pConn = (Connection *)conn;
    1772         Resource *pRes = pConn->pRes;
    1773         int rc = 0;
    1774         unsigned long action;
    1775 
    1776         smbwrp_fileinfo finfo;
    1777         char path[CCHMAXPATH+1] = {0};
    1778 
    1779         ENTER();
    1780 
    1781         debuglocal(9,"NdpSetFileAttribute in [%p]\n", pConn);
    1782         do {
    1783                 rc = pathparser(pRes, pConn, szFileName, path);
    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         LEAVE();
    1796         return rc;
     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;
    17971708}
    17981709
    17991710int APIENTRY NdpFlush (HRESOURCE resource)
    18001711{
    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*/
    18061720#define ND_PL_INIT_THREAD 0xFFFF0000
    18071721
    18081722int APIENTRY NdpIOCTL (int type, HRESOURCE resource, char *path, int function, void *in, ULONG insize, PULONG poutlen)
    18091723{
    1810         if (function == ND_PL_INIT_THREAD)
    1811         {
    1812                 smbwrp_initthread();
    1813                 debuglocal(9, "NdpIOCTL init thread\n");
    1814                 return NO_ERROR;
    1815         }
    1816 
    1817         debuglocal(9,"NdpIOCTL <%s> %d\n", path, function);
    1818 
    1819         if (in && insize > 4096)
    1820         {
    1821                 char out[4096];
    1822                 sprintf (out, "SAMBA IOCTL function = %d, parms [%s] insize = %d, *poutlen = %d", function, in, insize, *poutlen);
    1823                 *poutlen = strlen(out);
    1824                 strcpy (in, out);
    1825                 return NO_ERROR;
    1826         }
    1827 
    1828         return ERROR_NOT_SUPPORTED;
     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;
    18291743}
    18301744
    18311745int APIENTRY NdpFileQueryInfo (HCONNECTION conn, NDFILEHANDLE handle, void *plist)
    18321746{
    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;
    18591775}
    18601776
    18611777int APIENTRY NdpFileEAQuery (HCONNECTION conn, NDFILEHANDLE handle, GEALIST *pGEAList, FEALIST *pFEAList)
    18621778{
    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;
    19251833}
    19261834
    19271835int APIENTRY NdpFileEASet (HCONNECTION conn, NDFILEHANDLE handle, FEALIST *pFEAList)
    19281836{
    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;
    19731879}
    19741880
    19751881int APIENTRY NdpFileEASize (HCONNECTION conn, NDFILEHANDLE handle, ULONG *pulEASize)
    19761882{
    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;
    20361935}
    20371936
    20381937int APIENTRY NdpFileSetInfo (HCONNECTION conn, NDFILEHANDLE handle, NDFILEINFOL *pfi)
    20391938{
    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;
    20691970}
    20701971
    20711972int APIENTRY NdpFileSetFilePtrL(HCONNECTION conn, NDFILEHANDLE handle, LONGLONG llOffset, ULONG ulMethod, LONGLONG *pllActual)
    20721973{
    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;
    20972000}
    20982001
    20992002int APIENTRY NdpFileSetFilePtr (HCONNECTION conn, NDFILEHANDLE handle, LONG lOffset, ULONG ulMethod, ULONG *pulActual)
    21002003{
    2101         LONGLONG llActual;
    2102         int rc = NdpFileSetFilePtrL(conn, handle, lOffset, ulMethod, &llActual);
    2103         *pulActual = llActual & 0xFFFFFFFF;
    2104         debuglocal(9,"NdpFileSetFilePtr %ld %lu %ld %d\n", lOffset, ulMethod, *pulActual, rc);
    2105         return rc;
     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;
    21062009}
    21072010
    21082011int APIENTRY NdpFileClose (HCONNECTION conn, NDFILEHANDLE handle)
    21092012{
    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;
    21342038}
    21352039
    21362040int APIENTRY NdpFileCommit (HCONNECTION conn, NDFILEHANDLE handle)
    21372041{
    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}
    21422045
    21432046int APIENTRY NdpFileNewSize (HCONNECTION conn, NDFILEHANDLE handle, ULONG ulLen)
    21442047{
    2145         int rc = NdpFileNewSizeL(conn, handle, ulLen);
    2146         debuglocal(9,"NdpFileNewSize %ld %d\n", ulLen, rc);
    2147         return rc;
     2048        int rc = NdpFileNewSizeL(conn, handle, ulLen);
     2049        debuglocal(9, "NdpFileNewSize %ld %d\n", ulLen, rc);
     2050        return rc;
    21482051}
    21492052
    21502053int APIENTRY NdpFileNewSizeL(HCONNECTION conn, NDFILEHANDLE handle, LONGLONG llLen)
    21512054{
    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;
    21742079}
    21752080
     
    21782083int APIENTRY NdpFileRead (HCONNECTION conn, NDFILEHANDLE handle, void *pBuffer, ULONG ulRead, ULONG *pulActual)
    21792084{
    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;
    22322131}
    22332132
    22342133int APIENTRY NdpFileWrite (HCONNECTION conn, NDFILEHANDLE handle, void *pBuffer, ULONG ulWrite, ULONG *pulActual)
    22352134{
    2236         Connection *pConn = (Connection *)conn;
    2237         Resource *pRes = pConn->pRes;
    2238         int rc = 0;
    2239         unsigned long done = 0;
    2240         unsigned long onedone;
    2241         unsigned long action;
    2242 
    2243         ENTER();
    2244 
    2245         debuglocal(9,"NdpFileWrite in [%p]\n", pConn);
    2246 
    2247         /* delete the dir cache
    2248         this was moved from NdpFileClose() becasue if there are a lot files in the tree all are reread
    2249         the problem when moved to here is, that last accessed time is not refreshed
    2250         if this is needed, a new function needs to be done to update only one file in the cache */
    2251         dircache_invalidate(pConn->file.fullname, pRes->pdc, 1);
    2252 
    2253         do {
    2254                 if (pConn->file.fd < 0)
    2255                 {
    2256                         rc = ERROR_INVALID_HANDLE;
    2257                         break;
    2258                 }
    2259                 rc = smbwrp_write(pConn->cli, &pConn->file, pBuffer, ulWrite, pulActual);
    2260 
    2261         } while (0);
    2262         debuglocal(9,"NdpFileWrite <%s> %lu %lu %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, ulWrite, *pulActual, rc);
    2263         LEAVE();
    2264         return rc;
    2265 }
    2266 
     2135        Connection *pConn = (Connection *)conn;
     2136        Resource *pRes = pConn->pRes;
     2137        int rc = 0;
     2138        unsigned long done = 0;
     2139        unsigned long onedone;
     2140        unsigned long action;
     2141
     2142        ENTER();
     2143
     2144        debuglocal(9, "NdpFileWrite in [%p]\n", pConn);
     2145
     2146        /*
     2147         * delete the dir cache
     2148         * This was moved from NdpFileClose() becasue if there are a lot files
     2149         * in the tree, all are reread. The problem when moved to here is, that
     2150         * the last accessed time is not refreshed. If this is needed,
     2151         * a new function needs to be done to update only one file in the cache
     2152        */
     2153        dircache_invalidate(pConn->file.fullname, pRes->pdc, 1);
     2154
     2155        do {
     2156           if (pConn->file.fd < 0)
     2157           {
     2158              rc = ERROR_INVALID_HANDLE;
     2159              break;
     2160           }
     2161           rc = smbwrp_write(pConn->cli, &pConn->file, pBuffer, ulWrite, pulActual);
     2162
     2163        } while (0);
     2164
     2165        debuglocal(9, "NdpFileWrite <%s> %lu %lu %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, ulWrite, *pulActual, rc);
     2166
     2167        LEAVE();
     2168        return rc;
     2169}
Note: See TracChangeset for help on using the changeset viewer.