Author: jra Date: 2005-06-10 23:13:25 +0000 (Fri, 10 Jun 2005) New Revision: 7474
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=7474 Log: A *foul* and *disgusting* hack to ensure that, at the very lowest level, . and .. are the first two entries returned when reading a directory. This also means we can't seek to these offsets, but we will never be doing that anyway (as far as I can think). The reason we have to do this is that the NT4 explorer will happily display a folder marked ".." as a clickable folder (and probably would display "." as a clickable folder too) if these are not in positions zero and one of the returned file list. W2K seems to have fixed this but there are too many older systems out there... Never mind, more for the "Undocumented CIFS talk", coming to a CIFS2005 conference near you soon.... :-). Jeremy. Modified: branches/SAMBA_3_0/source/smbd/dir.c Changeset: Modified: branches/SAMBA_3_0/source/smbd/dir.c =================================================================== --- branches/SAMBA_3_0/source/smbd/dir.c 2005-06-10 23:13:21 UTC (rev 7473) +++ branches/SAMBA_3_0/source/smbd/dir.c 2005-06-10 23:13:25 UTC (rev 7474) @@ -42,6 +42,7 @@ char *dir_path; struct name_cache_entry *name_cache; unsigned int name_cache_index; + unsigned int file_number; }; struct dptr_struct { @@ -1074,15 +1075,35 @@ const char *n; connection_struct *conn = dirp->conn; - SeekDir(dirp, *poffset); + /* Cheat to allow . and .. to be the first entries returned. */ + if ((*poffset == 0) && (dirp->file_number < 2)) { + if (dirp->file_number == 0) { + n = "."; + } else { + n = ".."; + } + dirp->file_number++; + return n; + } else { + /* A real offset, seek to it. */ + SeekDir(dirp, *poffset); + } + while ((n = vfs_readdirname(conn, dirp->dir))) { struct name_cache_entry *e; + /* Ignore . and .. - we've already returned them. */ + if (*n == '.') { + if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) { + continue; + } + } dirp->offset = SMB_VFS_TELLDIR(conn, dirp->dir); dirp->name_cache_index = (dirp->name_cache_index+1) % NAME_CACHE_SIZE; e = &dirp->name_cache[dirp->name_cache_index]; SAFE_FREE(e->name); e->name = SMB_STRDUP(n); *poffset = e->offset= dirp->offset; + dirp->file_number++; return e->name; } dirp->offset = -1; @@ -1141,6 +1162,7 @@ /* Not found in the name cache. Rewind directory and start from scratch. */ SMB_VFS_REWINDDIR(conn, dirp->dir); + dirp->file_number = 0; *poffset = 0; while ((entry = ReadDirName(dirp, poffset))) { if (conn->case_sensitive ? (strcmp(entry, name) == 0) : strequal(entry, name)) {