Esempio n. 1
0
/* opendir() - The case insensitive version of opendir */
DIR *
opendir(const char *path)
{
    DIR *tDir;
    HANDLE tH;
    char tPath[MAX_PATH];
    WIN32_FIND_DATA tData;
    int ntErr;

    (void)strcpy(tPath, path);
    (void)strcat(tPath, "\\*");
    tH = FindFirstFile(tPath, &tData);

    if (tH == INVALID_HANDLE_VALUE) {
	ntErr = GetLastError();
	switch (ntErr) {
	case ERROR_DIRECTORY:
	    errno = ENOTDIR;
	    return (DIR *) 0;
	case ERROR_BAD_PATHNAME:
	    /* AFS NT client returns ERROR_BAD_PATHNAME where it should return
	     * ERROR_DIRECTORY.
	     */
	case ERROR_FILE_NOT_FOUND:
	    /* If at the "root" directory, then this can happen if it's empty.
	     */
	    {
		struct stat status;
		size_t len = strlen(tPath) - 1;
		tPath[len] = '\0';
		if (len >= 2 && tPath[len - 2] != ':') {
		    tPath[len - 1] = '\0';
		}
		if (stat(tPath, &status) < 0) {
		    errno = nterr_nt2unix(GetLastError(), ENOENT);
		    return (DIR *) 0;
		}
		if (!(status.st_mode & _S_IFDIR)) {
		    errno = ENOTDIR;
		    return (DIR *) 0;
		}
	    }
	    break;
	default:
	    errno = nterr_nt2unix(GetLastError(), ENOENT);
	    return (DIR *) 0;
	}
    }

    tDir = calloc(1, sizeof(DIR));
    if (!tDir) {
	errno = ENOMEM;
    } else {
	tDir->h = tH;
	tDir->data = tData;
    }
    return tDir;
}
Esempio n. 2
0
int
nt_seek(FD_t fd, afs_foff_t off, int whence)
{
    int code;
    LARGE_INTEGER offset;
    int where;

    if (SEEK_SET == whence) {
	where = FILE_BEGIN;
    } else if (SEEK_END == whence) {
	where = FILE_END;
    } else if (SEEK_CUR == whence) {
	where = FILE_CURRENT;
    } else {
	errno = EINVAL;
	return -1;
    }
    offset.QuadPart = off;

    code = SetFilePointerEx(fd, offset, NULL, where);
    if (0 == code) {
	errno = nterr_nt2unix(GetLastError(), EBADF);
	return -1;
    }
    return 0;
}
Esempio n. 3
0
int
nt_sync(int cdrive)
{
    FD_t drive_fd;
    char sdrive[32];
    int n;

    n = cdrive;
    if (n <= 26) {
	cdrive = 'A' + (n - 1);
    }

    cdrive = _toupper(cdrive);

    (void)sprintf(sdrive, "\\\\.\\%c:", cdrive);
    drive_fd = nt_open(sdrive, O_RDWR, 0666);
    if (drive_fd == INVALID_FD) {
	return -1;
    }

    if (!FlushFileBuffers((HANDLE) drive_fd)) {
	errno = nterr_nt2unix(GetLastError(), EBADF);
	nt_close(drive_fd);
	return -1;
    }
    nt_close(drive_fd);
    return 0;
}
Esempio n. 4
0
int
nt_pread(FD_t fd, void * buf, afs_sfsize_t count, afs_foff_t offset)
{
    /*
     * This really ought to call NtReadFile
     */
    DWORD nbytes;
    BOOL code;
    OVERLAPPED overlap = {0};
    LARGE_INTEGER liOffset;
    /*
     * Cast through a LARGE_INTEGER - make no assumption about
     * byte ordering and leave that to the compiler..
     */
    liOffset.QuadPart = offset;
    overlap.Offset = liOffset.LowPart;
    overlap.OffsetHigh = liOffset.HighPart;

    code = ReadFile((HANDLE) fd, (void *)buf, (DWORD) count, &nbytes, &overlap);

    if (!code) {
        DWORD gle = GetLastError();
        if (gle != ERROR_HANDLE_EOF) {
	        errno = nterr_nt2unix(GetLastError(), EBADF);
	        return -1;
        }
    }
    return (ssize_t)nbytes;
}
Esempio n. 5
0
/*
 * vpt_RemoveEntry() -- Remove vice partition table entry.
 *
 * RETURN CODES: 0 success, -1 failed (errno set)
 */
int
vpt_RemoveEntry(const char *vpname)
{
    long status;
    HKEY tabKey;

    if (!vpt_PartitionNameValid(vpname)) {
	errno = EINVAL;
	return -1;
    }

    /* open canonical Afstab key */
    status = RegOpenKeyAlt(AFSREG_NULL_KEY, AFSREG_SVR_SVC_AFSTAB_KEY,
			   KEY_WRITE, 0, &tabKey, NULL);

    if (status == ERROR_SUCCESS) {
	/* delete key representing vice partition */
	status = RegDeleteKey(tabKey, vpname);
    }

    if (status) {
	errno = nterr_nt2unix(status, EIO);
	return -1;
    }
    return 0;
}
Esempio n. 6
0
/* Currently nt_ftruncate only tested to shrink a file. */
int
nt_ftruncate(FD_t fd, afs_foff_t len)
{
    LARGE_INTEGER length;

    length.QuadPart = len;

    if (SetFilePointerEx(fd, length, NULL, FILE_BEGIN)
        == 0xffffffff) {
	errno = nterr_nt2unix(GetLastError(), EBADF);
	return -1;
    }
    if (!SetEndOfFile(fd)) {
	errno = nterr_nt2unix(GetLastError(), EBADF);
	return -1;
    }
    return 0;
}
Esempio n. 7
0
int
nt_close(FD_t fd)
{
    BOOL code;

    code = CloseHandle(fd);
    if (!code) {
	errno = nterr_nt2unix(GetLastError(), EBADF);
	return -1;
    }
    return 0;
}
Esempio n. 8
0
/* nt_open - open an NT handle for a file.
 *
 * Return Value:
 *	the handle or -1 on error.
 */
FD_t
nt_open(const char *name, int flags, int mode)
{
    HANDLE fh;
    DWORD nt_access = 0;
    DWORD nt_share = FILE_SHARE_READ;
    DWORD nt_create = 0;
    /* Really use the sequential one for data files, random for meta data. */
    DWORD FandA = BASEFILEATTRIBUTE | FILE_FLAG_SEQUENTIAL_SCAN;

    /* set access */
    if ((flags & O_RDWR) || (flags & O_WRONLY)) {
	nt_access |= GENERIC_WRITE;
        nt_share  |= FILE_SHARE_WRITE | FILE_SHARE_DELETE;
    }
    if ((flags & O_RDWR) || (flags == O_RDONLY))
	nt_access |= GENERIC_READ;

    /* set creation */
    switch (flags & (O_CREAT | O_EXCL | O_TRUNC)) {
    case 0:
	nt_create = OPEN_EXISTING;
	break;
    case O_CREAT:
	nt_create = OPEN_ALWAYS;
	break;
    case O_CREAT | O_TRUNC:
	nt_create = CREATE_ALWAYS;
	break;
    case O_CREAT | O_EXCL:
    case O_CREAT | O_EXCL | O_TRUNC:
	nt_create = CREATE_NEW;
	break;
    case O_TRUNC:
	nt_create = TRUNCATE_EXISTING;
	break;
    case O_TRUNC | O_EXCL:
    case O_EXCL:
    default:
	errno = EINVAL;
	return INVALID_FD;
	break;
    }

    fh = CreateFile(name, nt_access, nt_share, NULL, nt_create, FandA, NULL);
    if (fh == INVALID_HANDLE_VALUE) {
        DWORD gle = GetLastError();
        errno = nterr_nt2unix(gle, EBADF);
    }
    return fh;
}
Esempio n. 9
0
int
nt_write(FD_t fd, void *buf, afs_sfsize_t size)
{
    BOOL code;
    DWORD nbytes;

    code = WriteFile((HANDLE) fd, buf, (DWORD) size, &nbytes, NULL);

    if (!code) {
	errno = nterr_nt2unix(GetLastError(), EBADF);
	return -1;
    }
    return (int)nbytes;
}
Esempio n. 10
0
/*
 * renamefile() -- rename a file (Unix rename() semantics)
 */
int
renamefile(const char *oldname, const char *newname)
{
    int rc = 0;

#ifdef AFS_NT40_ENV
    if (!MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING)) {
	/* rename failed */
	errno = nterr_nt2unix(GetLastError(), EIO);
	rc = -1;
    }
#else
    rc = rename(oldname, newname);
#endif
    return rc;
}
Esempio n. 11
0
int
nt_read(FD_t fd, void *buf, afs_sfsize_t size)
{
    BOOL code;
    DWORD nbytes;

    code = ReadFile((HANDLE) fd, buf, (DWORD) size, &nbytes, NULL);

    if (!code) {
        DWORD gle = GetLastError();
        if (gle != ERROR_HANDLE_EOF) {
	        errno = nterr_nt2unix(GetLastError(), EBADF);
	        return -1;
        }
    }
    return (int)nbytes;
}
Esempio n. 12
0
/* nt_unlink - unlink a case sensitive name.
 *
 * nt_unlink supports the nt_dec call.
 *
 * This nt_unlink has the delete on last close semantics of the Unix unlink
 * with a minor twist. Subsequent CreateFile calls on this file can succeed
 * if they open for delete. If a CreateFile call tries to create a new file
 * with the same name it will fail. Fortunately, neither case should occur
 * as part of nt_dec.
 */
int
nt_unlink(char *name)
{
    HANDLE fh;

    fh = CreateFile(name,
                    GENERIC_READ | GENERIC_WRITE | DELETE,
		    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
		    NULL, OPEN_EXISTING,
		    BASEFILEATTRIBUTE | FILE_FLAG_DELETE_ON_CLOSE | FILE_FLAG_POSIX_SEMANTICS,
                    NULL);
    if (fh != INVALID_HANDLE_VALUE)
	CloseHandle(fh);
    else {
	errno = nterr_nt2unix(GetLastError(), ENOENT);
	return -1;
    }
    return 0;
}
Esempio n. 13
0
/*
 * vpt_AddEntry() -- Add or update vice partition table entry.
 *
 * RETURN CODES: 0 success, -1 failed (errno set)
 */
int
vpt_AddEntry(const struct vptab *vptabp)
{
    long status;
    HKEY tabKey, vpKey;
    const char *vpName, *vpDev;

    vpName = vptabp->vp_name;
    vpDev = vptabp->vp_dev;

    if (!vpt_PartitionNameValid(vpName) || !vpt_DeviceNameValid(vpDev)) {
	errno = EINVAL;
	return -1;
    }

    /* open canonical Afstab key; create if doesn't exist */
    status = RegOpenKeyAlt(AFSREG_NULL_KEY, AFSREG_SVR_SVC_AFSTAB_KEY,
			   KEY_WRITE, 1 /* create */, &tabKey, NULL);

    if (status == ERROR_SUCCESS) {
	/* open key representing vice partition; create if doesn't exist */
	status = RegOpenKeyAlt(tabKey, vpName,
			       KEY_WRITE, 1 /* create */, &vpKey, NULL);

	if (status == ERROR_SUCCESS) {
	    /* write partition attributes */
	    status = RegSetValueEx(vpKey, AFSREG_SVR_SVC_AFSTAB_DEVNAME_VALUE,
				   0, REG_SZ, vpDev, (DWORD)strlen(vpDev) + 1);

	    RegCloseKey(vpKey);
	}

	RegCloseKey(tabKey);
    }

    if (status) {
	errno = nterr_nt2unix(status, EIO);
	return -1;
    }
    return 0;
}
Esempio n. 14
0
struct dirent *
readdir(DIR * dir)
{
    int rc;

    if (!dir) {
	errno = EBADF;
	return (struct dirent *)0;
    }

    errno = 0;
    if (dir->h == INVALID_HANDLE_VALUE)
	return (struct dirent *)0;

    if (dir->first) {
	dir->first = 0;
    } else {
	while (rc = FindNextFile(dir->h, &dir->data)) {
	    if ((strcmp(dir->data.cFileName, ".") == 0)
		|| (strcmp(dir->data.cFileName, "..") == 0)) {

		continue;	/* skip "." and ".." */
	    }
	    break;		/* found a non '.' or '..' entry. */
	}
	if (rc == 0) {		/* FindNextFile() failed */
	    if (GetLastError() == ERROR_NO_MORE_FILES)
		return (struct dirent *)0;
	    else {
		errno = nterr_nt2unix(GetLastError(), EBADF);
		return (struct dirent *)0;
	    }
	}
    }

    dir->cdirent.d_name = dir->data.cFileName;
    return &dir->cdirent;
}
Esempio n. 15
0
int
vpt_Start(struct vpt_iter *iterp)  /* [out] iteration handle to initialize */
{
    long status;
    HKEY key;

    memset(iterp, 0, sizeof(*iterp));

    /* open canonical Afstab key */
    status = RegOpenKeyAlt(AFSREG_NULL_KEY, AFSREG_SVR_SVC_AFSTAB_KEY,
			   KEY_READ, 0, &key, NULL);

    if (status == ERROR_SUCCESS) {
	/* enumerate subkeys, each of which represents a vice partition */
	status = RegEnumKeyAlt(key, &iterp->vpenum);
	(void)RegCloseKey(key);
    }

    if (status) {
	errno = nterr_nt2unix(status, EIO);
	return -1;
    }
    return 0;
}
Esempio n. 16
0
int
nt_pwrite(FD_t fd, const void * buf, afs_sfsize_t count, afs_foff_t offset)
{
    /*
     * same comment as read
     */

    DWORD nbytes;
    BOOL code;
    OVERLAPPED overlap = {0};
    LARGE_INTEGER liOffset;

    liOffset.QuadPart = offset;
    overlap.Offset = liOffset.LowPart;
    overlap.OffsetHigh = liOffset.HighPart;

    code = WriteFile((HANDLE) fd, (void *)buf, (DWORD) count, &nbytes, &overlap);

    if (!code) {
	errno = nterr_nt2unix(GetLastError(), EBADF);
	return -1;
    }
    return (ssize_t)nbytes;
}
Esempio n. 17
0
int
vpt_NextEntry(struct vpt_iter *iterp,   /* [in] valid iteration handle */
	      struct vptab *vptabp)    /* [out] next partiton table entry */
{
    long status;
    HKEY tabKey, vpKey;
    char *nextNamep;

    if (iterp->vpenum == NULL) {
	/* no partition entries (or invalid iteration handle) */
	errno = ENOENT;
	return -1;
    }

    /* find name of next partition entry to examine in multistring enum */
    if (iterp->last == NULL) {
	/* first call */
	nextNamep = iterp->last = iterp->vpenum;
    } else {
	/* subsequent call */
	if (*iterp->last != '\0') {
	    /* not at end of multistring; advance to next name */
	    iterp->last += strlen(iterp->last) + 1;
	}
	nextNamep = iterp->last;
    }

    if (*nextNamep == '\0') {
	/* end of multistring; no more entries */
	errno = ENOENT;
	return -1;
    }

    if (strlen(nextNamep) >= VPTABSIZE_NAME) {
	/* invalid partition name entry */
	errno = EINVAL;
	return -1;
    }
    strcpy(vptabp->vp_name, nextNamep);

    /* open canonical Afstab key */
    status = RegOpenKeyAlt(AFSREG_NULL_KEY, AFSREG_SVR_SVC_AFSTAB_KEY,
			   KEY_READ, 0, &tabKey, NULL);

    if (status == ERROR_SUCCESS) {
	/* open key representing vice partition */
	status = RegOpenKeyAlt(tabKey, nextNamep,
			       KEY_READ, 0, &vpKey, NULL);

	if (status == ERROR_SUCCESS) {
	    /* read partition attributes */
	    DWORD dataType, dataSize = VPTABSIZE_DEV;

	    status = RegQueryValueEx(vpKey,
				     AFSREG_SVR_SVC_AFSTAB_DEVNAME_VALUE,
				     NULL, &dataType, vptabp->vp_dev,
				     &dataSize);

	    if (status == ERROR_SUCCESS && dataType != REG_SZ) {
		/* invalid device name type */
		status = ERROR_INVALID_PARAMETER;
	    }
	    (void)RegCloseKey(vpKey);
	}
	(void)RegCloseKey(tabKey);
    }

    if (status) {
	errno = nterr_nt2unix(status, EIO);
	return -1;
    }
    return 0;
}