Esempio n. 1
0
char *win32_getcwd(char *buf, int maxlen)
{
	int n=0;

	if(p_GetCurrentDirectoryW)
	{
		char *pwszBuf=sm_get_pool_memory(PM_FNAME);
		pwszBuf=sm_check_pool_memory_size(pwszBuf,
			maxlen*sizeof(wchar_t));

		if((n=p_GetCurrentDirectoryW(maxlen, (LPWSTR)pwszBuf)))
			n=wchar_2_UTF8(buf, (wchar_t *)pwszBuf, maxlen)-1;
		sm_free_pool_memory(pwszBuf);
	}
	else if(p_GetCurrentDirectoryA)
		n=p_GetCurrentDirectoryA(maxlen, buf);

	if(!n || n>maxlen) return NULL;

	if(n+1 > maxlen) return NULL;
	if(n!=3)
	{
		buf[n]='\\';
		buf[n+1]=0;
	}
	return buf;
}
Esempio n. 2
0
/*
 * Generate a valid connect string and the backup command we should execute
 * in the seperate database controling thread.
 */
static inline void perform_ado_backup(bpContext *ctx)
{
    plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext;
    POOL_MEM ado_connect_string(PM_NAME),
             ado_query(PM_NAME);
    POOLMEM *vdsname;

    /*
     * If no explicit instance name given usedthe DEFAULT_INSTANCE name.
     */
    if (!p_ctx->instance) {
        p_ctx->instance = bstrdup(DEFAULT_INSTANCE);
    }

    set_ado_connect_string(ctx);

    vdsname = get_pool_memory(PM_NAME);
    wchar_2_UTF8(&vdsname, p_ctx->vdsname);

    switch (p_ctx->backup_level) {
    case L_INCREMENTAL:
        Mmsg(ado_query,
             "BACKUP LOG %s TO VIRTUAL_DEVICE='%s' WITH BLOCKSIZE=%d, BUFFERCOUNT=%d, MAXTRANSFERSIZE=%d",
             p_ctx->database,
             vdsname,
             DEFAULT_BLOCKSIZE,
             DEFAULT_BUFFERS,
             DEFAULT_BLOCKSIZE);
        break;
    case L_DIFFERENTIAL:
        Mmsg(ado_query,
             "BACKUP DATABASE %s TO VIRTUAL_DEVICE='%s' WITH DIFFERENTIAL, BLOCKSIZE=%d, BUFFERCOUNT=%d, MAXTRANSFERSIZE=%d",
             p_ctx->database,
             vdsname,
             DEFAULT_BLOCKSIZE,
             DEFAULT_BUFFERS,
             DEFAULT_BLOCKSIZE);
        break;
    default:
        Mmsg(ado_query,
             "BACKUP DATABASE %s TO VIRTUAL_DEVICE='%s' WITH BLOCKSIZE=%d, BUFFERCOUNT=%d, MAXTRANSFERSIZE=%d",
             p_ctx->database,
             vdsname,
             DEFAULT_BLOCKSIZE,
             DEFAULT_BUFFERS,
             DEFAULT_BLOCKSIZE);
        break;
    }

    Dmsg(ctx, dbglvl, "perform_ado_backup: ADO Query '%s'\n", ado_query.c_str());

    p_ctx->ado_query = bstrdup(ado_query.c_str());
    free_pool_memory(vdsname);
}
Esempio n. 3
0
int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
{
	_dir *dp=(_dir *)dirp;
	if(dp->valid_w || dp->valid_a)
	{
		entry->d_off=dp->offset;

		// Copy unicode.
		if(dp->valid_w)
		{
			char szBuf[MAX_PATH_UTF8+1];
			wchar_2_UTF8(szBuf, dp->data_w.cFileName);
			dp->offset+=copyin(*entry, szBuf);
		}
		else if(dp->valid_a) // copy ansi (only 1 will be valid)
			dp->offset+=copyin(*entry, dp->data_a.cFileName);

		*result=entry; // Return entry address.
	}
	else
	{
		errno=b_errno_win32;
		return -1;
	}

	// Get next file, try unicode first.
	if(p_FindNextFileW)
		dp->valid_w=p_FindNextFileW(dp->dirh, &dp->data_w);
	else if(p_FindNextFileA)
		dp->valid_a=p_FindNextFileA(dp->dirh, &dp->data_a);
	else
	{
		dp->valid_a=FALSE;
		dp->valid_w=FALSE;
	}

	return 0;
}
Esempio n. 4
0
static int statDir(const char *file, struct stat *sb, uint64_t *winattr)
{
	WIN32_FIND_DATAW info_w; // window's file info
	WIN32_FIND_DATAA info_a; // window's file info

	// cache some common vars to make code more transparent
	DWORD *pdwFileAttributes;
	DWORD *pnFileSizeHigh;
	DWORD *pnFileSizeLow;
	DWORD *pdwReserved0;
	FILETIME *pftLastAccessTime;
	FILETIME *pftLastWriteTime;
	FILETIME *pftCreationTime;

	/* Oh, cool, another exception: Microsoft doesn't let us do 
	   FindFile operations on a Drive, so simply fake root attibutes. */
	if(file[1]==':' && !file[2])
	{
		time_t now=time(NULL);
		sb->st_mode=S_IFDIR;
		sb->st_mode|=S_IREAD|S_IEXEC|S_IWRITE;
		sb->st_ctime=now;
		sb->st_mtime=now;
		sb->st_atime=now;
		sb->st_rdev=0;
		return 0;
	}

	HANDLE h=INVALID_HANDLE_VALUE;

	// use unicode
	if(p_FindFirstFileW)
	{
		char *pwszBuf=sm_get_pool_memory(PM_FNAME);
		make_win32_path_UTF8_2_wchar(&pwszBuf, file);

		h=p_FindFirstFileW((LPCWSTR)pwszBuf, &info_w);
		sm_free_pool_memory(pwszBuf);

		pdwFileAttributes=&info_w.dwFileAttributes;
		pdwReserved0     =&info_w.dwReserved0;
		pnFileSizeHigh   =&info_w.nFileSizeHigh;
		pnFileSizeLow    =&info_w.nFileSizeLow;
		pftLastAccessTime=&info_w.ftLastAccessTime;
		pftLastWriteTime =&info_w.ftLastWriteTime;
		pftCreationTime  =&info_w.ftCreationTime;
		// use ASCII
	}
	else if (p_FindFirstFileA)
	{
		h=p_FindFirstFileA(file, &info_a);

		pdwFileAttributes=&info_a.dwFileAttributes;
		pdwReserved0     =&info_a.dwReserved0;
		pnFileSizeHigh   =&info_a.nFileSizeHigh;
		pnFileSizeLow    =&info_a.nFileSizeLow;
		pftLastAccessTime=&info_a.ftLastAccessTime;
		pftLastWriteTime =&info_a.ftLastWriteTime;
		pftCreationTime  =&info_a.ftCreationTime;
	}

	if(h==INVALID_HANDLE_VALUE)
	{
		const char *err = errorString();
		/* Note, in creating leading paths, it is normal that
		   the file does not exist. */
		LocalFree((void *)err);
		errno=b_errno_win32;
		return -1;
	}
	else
		FindClose(h);

	*winattr=(int64_t)*pdwFileAttributes;

	/* Graham says: all the following stuff seems rather complicated.
	   It is probably not all needed anymore, since I have added *winattr
	   above, which bacula did not do.
	   One reason for keeping it is that some of the values get converted
	   to unix-style permissions that show up in the long list
	   functionality.
	   I think I would prefer to remove it all at some point. */

	sb->st_mode = 0777;  // start with everything
	if(*pdwFileAttributes & FILE_ATTRIBUTE_READONLY)
		sb->st_mode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
	if(*pdwFileAttributes & FILE_ATTRIBUTE_SYSTEM)
		sb->st_mode &= ~S_IRWXO; // remove everything for other
	if(*pdwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
		sb->st_mode |= S_ISVTX; // use sticky bit -> hidden
	sb->st_mode |= S_IFDIR;

	/* Store reparse/mount point info in st_rdev.  Note a
	   Win32 reparse point (junction point) is like a link
	   though it can have many properties (directory link,
	   soft link, hard link, HSM, ...
	   A mount point is a reparse point where another volume
	   is mounted, so it is like a Unix mount point (change of
	   filesystem).  */
	if(*pdwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
		sb->st_rdev=WIN32_MOUNT_POINT;
	else
		sb->st_rdev=0;

	if((*pdwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
	  && (*pdwReserved0 & IO_REPARSE_TAG_MOUNT_POINT))
	{
		sb->st_rdev=WIN32_MOUNT_POINT;
		/* Now to find out if the directory is a mount point or
		   a reparse point, we must do a song and a dance.
		   Explicitly open the file to read the reparse point, then
		   call DeviceIoControl to find out if it points to a Volume
		   or to a directory. */
		h=INVALID_HANDLE_VALUE;
		if(p_GetFileAttributesW)
		{
			char *pwszBuf=sm_get_pool_memory(PM_FNAME);
			make_win32_path_UTF8_2_wchar(&pwszBuf, file);
			if(p_CreateFileW)
			{
				h=CreateFileW((LPCWSTR)pwszBuf, GENERIC_READ,
					FILE_SHARE_READ, NULL, OPEN_EXISTING,
					FILE_FLAG_BACKUP_SEMANTICS
					| FILE_FLAG_OPEN_REPARSE_POINT,
					NULL);
			}
			sm_free_pool_memory(pwszBuf);
		}
		else if(p_GetFileAttributesA)
		{
			h=CreateFileA(file, GENERIC_READ,
				FILE_SHARE_READ, NULL, OPEN_EXISTING,
				FILE_FLAG_BACKUP_SEMANTICS
				| FILE_FLAG_OPEN_REPARSE_POINT,
				NULL);
		}
		if(h!=INVALID_HANDLE_VALUE)
		{
			char dummy[1000];
			REPARSE_DATA_BUFFER *rdb=(REPARSE_DATA_BUFFER *)dummy;
			rdb->ReparseTag=IO_REPARSE_TAG_MOUNT_POINT;
			DWORD bytes;
			bool ok;
			ok=DeviceIoControl(h, FSCTL_GET_REPARSE_POINT,
				NULL, 0, // in buffer, bytes
				(LPVOID)rdb,
				(DWORD)sizeof(dummy), // out buffer, btyes
				(LPDWORD)&bytes, (LPOVERLAPPED)0);
			if(ok)
			{
				char *utf8=sm_get_pool_memory(PM_NAME);
				wchar_2_UTF8(utf8, (wchar_t *)
				  rdb->SymbolicLinkReparseBuffer.PathBuffer);
				if(!strncasecmp(utf8, "\\??\\volume{", 11))
					sb->st_rdev=WIN32_MOUNT_POINT;
				else // Points to a directory so we ignore it. 
					sb->st_rdev=WIN32_JUNCTION_POINT;
				sm_free_pool_memory(utf8);
			}
			CloseHandle(h);
		}
	}
	sb->st_size=*pnFileSizeHigh;
	sb->st_size<<=32;
	sb->st_size|=*pnFileSizeLow;
	sb->st_blksize=4096;
	sb->st_blocks=(uint32_t)(sb->st_size+4095)/4096;

	sb->st_atime=cvt_ftime_to_utime(*pftLastAccessTime);
	sb->st_mtime=cvt_ftime_to_utime(*pftLastWriteTime);
	sb->st_ctime=cvt_ftime_to_utime(*pftCreationTime);

	return 0;
}
Esempio n. 5
0
char* win32_cgets (char* buffer, int len)
{
	/* We use console ReadConsoleA / ReadConsoleW to be able to read
	   unicode from the win32 console and fallback if seomething fails. */

	HANDLE hIn=GetStdHandle (STD_INPUT_HANDLE);
	if(hIn
	  && (hIn!=INVALID_HANDLE_VALUE)
	    && p_WideCharToMultiByte && p_MultiByteToWideChar)
	{
		DWORD dwRead;
		wchar_t wszBuf[1024];
		char  szBuf[1024];

		// NT and unicode conversion.
		if(ReadConsoleW(hIn, wszBuf, 1024, &dwRead, NULL))
		{
			// Null terminate at end.
			if(wszBuf[dwRead-1]==L'\n')
			{
				wszBuf[dwRead-1]=L'\0';
				dwRead--;
			}

			if(wszBuf[dwRead-1]==L'\r')
			{
				wszBuf[dwRead-1]=L'\0';
				dwRead--;
			}

			wchar_2_UTF8(buffer, wszBuf, len);
			return buffer;
		}

		// Win 9x and unicode conversion.
		if(ReadConsoleA(hIn, szBuf, 1024, &dwRead, NULL))
		{
			// Null terminate at end.
			if(szBuf[dwRead-1]==L'\n')
			{
				szBuf[dwRead-1]=L'\0';
				dwRead--;
			}

			if(szBuf[dwRead-1]==L'\r')
			{
				szBuf[dwRead-1]=L'\0';
				dwRead--;
			}

			// Convert from ansii to wchar_t.
			p_MultiByteToWideChar(GetConsoleCP(),
				0, szBuf, -1, wszBuf, 1024);
			// Convert from wchar_t to UTF-8.
			if(wchar_2_UTF8(buffer, wszBuf, len))
				return buffer;
		}
	}

	// Fallback.
	if(fgets(buffer, len, stdin)) return buffer;
	return NULL;
}
Esempio n. 6
0
/*
 * Generate a valid connect string and the restore command we should execute
 * in the seperate database controling thread.
 */
static inline void perform_ado_restore(bpContext *ctx)
{
    POOL_MEM ado_query(PM_NAME),
             temp(PM_NAME);
    POOLMEM *vdsname;
    plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext;

    /*
     * If no explicit instance name given use the DEFAULT_INSTANCE name.
     */
    if (!p_ctx->instance) {
        p_ctx->instance = bstrdup(DEFAULT_INSTANCE);
    }

    set_ado_connect_string(ctx);

    vdsname = get_pool_memory(PM_NAME);
    wchar_2_UTF8(&vdsname, p_ctx->vdsname);

    switch (p_ctx->backup_level) {
    case L_INCREMENTAL:
        Mmsg(ado_query,
             "RESTORE LOG %s FROM VIRTUAL_DEVICE='%s' WITH BLOCKSIZE=%d, BUFFERCOUNT=%d, MAXTRANSFERSIZE=%d, %s",
             p_ctx->database,
             vdsname,
             DEFAULT_BLOCKSIZE,
             DEFAULT_BUFFERS,
             DEFAULT_BLOCKSIZE,
             p_ctx->DoNoRecovery ? "NORECOVERY" : "RECOVERY");
        break;
    default:
        Mmsg(ado_query,
             "RESTORE DATABASE %s FROM VIRTUAL_DEVICE='%s' WITH BLOCKSIZE=%d, BUFFERCOUNT=%d, MAXTRANSFERSIZE=%d, %s",
             p_ctx->database,
             vdsname,
             DEFAULT_BLOCKSIZE,
             DEFAULT_BUFFERS,
             DEFAULT_BLOCKSIZE,
             p_ctx->DoNoRecovery ? "NORECOVERY" : "RECOVERY");
        break;
    }

    /*
     * See if we need to insert any stopbeforemark arguments.
     */
    if (p_ctx->stopbeforemark) {
        Mmsg(temp, ", STOPBEFOREMARK = '%s'", p_ctx->stopbeforemark);
        pm_strcat(ado_query, temp.c_str());
    }

    /*
     * See if we need to insert any stopatmark arguments.
     */
    if (p_ctx->stopatmark) {
        Mmsg(temp, ", STOPATMARK = '%s'", p_ctx->stopatmark);
        pm_strcat(ado_query, temp.c_str());
    }

    /*
     * See if we need to insert any stopat arguments.
     */
    if (p_ctx->stopat) {
        Mmsg(temp, ", STOPAT = '%s'", p_ctx->stopat);
        pm_strcat(ado_query, temp.c_str());
    }

    /*
     * See if we need to insert the REPLACE option.
     */
    if (p_ctx->ForceReplace) {
        pm_strcat(ado_query, ", REPLACE");
    }

    Dmsg(ctx, dbglvl, "perform_ado_restore: ADO Query '%s'\n", ado_query.c_str());

    p_ctx->ado_query = bstrdup(ado_query.c_str());
    free_pool_memory(vdsname);
}