Esempio n. 1
0
//this is the thread function which calls the subversion function
UINT CCacheDlg::WatchTestThread()
{
	CDirFileEnum direnum(m_sRootPath);
	m_filelist.RemoveAll();
	CString filepath;
	bool bIsDir = false;
	while (direnum.NextFile(filepath, &bIsDir))
		m_filelist.Add(filepath);

	CTime starttime = CTime::GetCurrentTime();
	GetDlgItem(IDC_STARTTIME)->SetWindowText(starttime.Format(_T("%H:%M:%S")));

	DWORD startticks = GetTickCount();

	CString sNumber;
	srand(GetTickCount());
	filepath = m_filelist.GetAt(rand() % m_filelist.GetCount());
	GetStatusFromRemoteCache(CTGitPath(m_sRootPath), false);
	for (int i=0; i < 10000; ++i)
	{
		filepath = m_filelist.GetAt(rand() % m_filelist.GetCount());
		GetDlgItem(IDC_FILEPATH)->SetWindowText(filepath);
		TouchFile(filepath);
		CopyRemoveCopy(filepath);
		sNumber.Format(_T("%d"), i);
		GetDlgItem(IDC_DONE)->SetWindowText(sNumber);
	}

	// create dummy directories and remove them again several times
	for (int outer = 0; outer<100; ++outer)
	{
		for (int i=0; i<10; ++i)
		{
			filepath.Format(_T("__MyDummyFolder%d"), i);
			CreateDirectory(m_sRootPath+_T("\\")+filepath, NULL);
			HANDLE hFile = CreateFile(m_sRootPath+_T("\\")+filepath+_T("\\file"), GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
			CloseHandle(hFile);
			SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH | SHCNF_FLUSHNOWAIT, m_sRootPath+_T("\\")+filepath+_T("\\file"), NULL);
		}
		Sleep(500);
		for (int i=0; i<10; ++i)
		{
			filepath.Format(_T("__MyDummyFolder%d"), i);
			DeleteFile(m_sRootPath+_T("\\")+filepath+_T("\\file"));
			RemoveDirectory(m_sRootPath+_T("\\")+filepath);
		}
		sNumber.Format(_T("%d"), outer);
		GetDlgItem(IDC_DONE)->SetWindowText(sNumber);
	}

	CTime endtime = CTime::GetCurrentTime();
	CString sEnd = endtime.Format(_T("%H:%M:%S"));

	DWORD endticks = GetTickCount();

	CString sEndText;
	sEndText.Format(_T("%s  - %ld ms"), sEnd, endticks-startticks);

	GetDlgItem(IDC_ENDTIME)->SetWindowText(sEndText);

	return 0;
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{

    LPVOID cdata = NULL;
    DWORD csz = 0;
    int ret = 0, argc;
    HRESULT hr;
    LPWSTR tgt = NULL, dest = NULL, *argv, unpack_dir = NULL;
    BOOL existing = false, launch = false, automated = false;
    WCHAR buf[4*MAX_PATH] = {0}, mb_msg[4*MAX_PATH] = {0}, fdest[4*MAX_PATH] = {0};

    if (!load_data(&cdata, &csz)) return 0;

    hr = CoInitialize(NULL);
    if (FAILED(hr)) { show_error(L"Failed to initialize COM"); return 0; }

    // Get the target directory for installation
    argv = CommandLineToArgvW(GetCommandLine(), &argc);
    if (argv == NULL) { show_last_error(L"Failed to get command line"); return 0; }
    if (argc > 1) {
        tgt = argv[1];
        automated = true;
    } else {
        tgt = get_directory_from_user();
        if (tgt == NULL) goto end;
    }

    if (!directory_exists(tgt)) {
        show_detailed_error(L"The specified directory does not exist: ",
                tgt, 1);
        goto end;
    }

    // Ensure the path to Calibre Portable is not too long
    do {
        if (!find_portable_dir(tgt, &dest, &existing)) goto end;

        if (GetFullPathName(dest, MAX_PATH*4, fdest, NULL) == 0) {
            show_last_error(L"Failed to resolve target folder");
            goto end;
        }
        free(dest); dest = NULL;

        if (wcslen(fdest) > 58) {
            _snwprintf_s(buf, 4*MAX_PATH, _TRUNCATE, 
                L"Path to Calibre Portable (%s) too long. Must be less than 59 characters.", fdest);
            if (!existing) RemoveDirectory(fdest);
            show_error(buf);
            tgt = get_directory_from_user();
            if (tgt == NULL) goto end;
        }
    } while (wcslen(fdest) > 58);

    // Confirm the user wants to upgrade
    if (existing && !automated) {
        _snwprintf_s(mb_msg, 4*MAX_PATH, _TRUNCATE, 
            L"An existing install of Calibre Portable was found at %s. Do you want to upgrade it?",
            fdest);
        if (MessageBox(NULL, mb_msg,
                L"Upgrade Calibre Portable?", MB_ICONEXCLAMATION | MB_YESNO | MB_TOPMOST) != IDYES)
            goto end;
    }

    if (existing) {
        if (!ensure_not_running(fdest)) goto end;
    }

    // Make a temp dir to unpack into
    if (!SetCurrentDirectoryW(fdest)) { show_detailed_error(L"Failed to change to unzip directory: ", fdest, 0); goto end; }

    if ( (unpack_dir = make_unpack_dir()) == NULL ) goto end;
    if (!SetCurrentDirectoryW(unpack_dir)) { show_detailed_error(L"Failed to change to unpack directory: ", fdest, 0); goto end; }

    // Extract files
    if (!extract(cdata, csz)) goto end;

    // Move files from temp dir to the install dir
    if (!move_program()) goto end;

    _snwprintf_s(mb_msg, 4*MAX_PATH, _TRUNCATE, 
        L"Calibre Portable successfully installed to %s. Launch calibre?",
        fdest);
    launch = MessageBox(NULL, mb_msg,
        L"Success", MB_ICONINFORMATION | MB_YESNO | MB_TOPMOST) == IDYES;

end:
    if (unpack_dir != NULL) { SetCurrentDirectoryW(L".."); rmtree(unpack_dir); free(unpack_dir); }
    CoUninitialize();
    if (launch) launch_calibre();
    return 0;
}
Esempio n. 3
0
BOOL DeleteDirectory(const WCHAR* sPathToDelete)
{
  BOOL            bResult = TRUE;
  HANDLE          hFile;
  WCHAR           sFilePath[MAX_PATH];
  WCHAR           sPattern[MAX_PATH];
  WIN32_FIND_DATA findData;

  wcscpy(sPattern, sPathToDelete);
  wcscat(sPattern, L"\\*.*");
  hFile = FindFirstFile(sPattern, &findData);
  if (hFile != INVALID_HANDLE_VALUE)
  {
    do
    {
      if (findData.cFileName[0] != L'.')
      {
        _snwprintf(sFilePath, MAX_PATH, L"%s\\%s", sPathToDelete, findData.cFileName);

        if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {
          // Delete subdirectory
          if (!DeleteDirectory(sFilePath))
            bResult = FALSE;
        }
        else
        {
          // Set file attributes
          if (SetFileAttributes(sFilePath, FILE_ATTRIBUTE_NORMAL))
          {
            // Delete file
            if (!DeleteFile(sFilePath) && nTotalRetries < c_nMaxTotalRetries)
            {
              BOOL bDeleted = FALSE;
              nTotalRetries++;
              for (int nRetry = 0; nRetry < c_nMaxOneFileRetries; nRetry++)
              {
                Sleep(c_nRetryDelay);
                if (DeleteFile(sFilePath))
                {
                  bDeleted = TRUE;
                  break;
                }
              }
              if (!bDeleted)
                bResult = FALSE;
            }
          }
        }
      }
    } while (FindNextFile(hFile, &findData));

    // Close handle
    FindClose(hFile);
  }

  // Set directory attributes
  if (SetFileAttributes(sPathToDelete, FILE_ATTRIBUTE_NORMAL))
  {
    g_nDirsDeleted++;
    UpdateProgress();
    // Delete directory
    if (!RemoveDirectory(sPathToDelete) && nTotalRetries < c_nMaxTotalRetries)
    {
      BOOL bDeleted = FALSE;
      nTotalRetries++;
      for (int nRetry = 0; nRetry < c_nMaxOneFileRetries; nRetry++)
      {
        Sleep(c_nRetryDelay);
        if (RemoveDirectory(sPathToDelete))
        {
          bDeleted = TRUE;
          break;
        }
      }
      if (!bDeleted)
        bResult = FALSE;
    }
  }

  return bResult;
}
Esempio n. 4
0
int qt_wince__rmdir(const char *dirname)
{
    return RemoveDirectory(reinterpret_cast<const wchar_t *> (QString::fromLatin1(dirname).utf16())) ? 0 : -1;
}
Esempio n. 5
0
// recursively remove a file branch
gbool GUrlCache::RemoveFiles(const char *directory,time_t olderThan)
{

    CFileFind finder;

    CString dir = directory;

    // add separator
    int l = dir.GetLength();
    if (l == 0) return FALSE;
    if ( !((dir[l-1] == '\\') || (dir[l-1] == '/'))) dir += '\\';

    dir += "*.*";

    CString path;

    CTime creationTime((time_t)0);
    CTime accessTime((time_t)0);
    CTime writeTime((time_t)0);

    // setup the find structure
    BOOL bWorking = finder.FindFile(dir);

    LONGLONG fileSum=0;

    while (bWorking)  { // for all entrys
        if (stop) break;

        bWorking = finder.FindNextFile();

        path = finder.GetFilePath();

        creationTime = (time_t)0;
        accessTime = (time_t)0;
        writeTime = (time_t)0;

        BOOL ret=finder.GetCreationTime(creationTime);
        finder.GetLastAccessTime(accessTime);
        finder.GetLastWriteTime(writeTime);
        time_t t = creationTime.GetTime();

        // if (accessTime.GetTime()>0) t = max(t,accessTime.GetTime());


        if (finder.IsDots( )) {	// ignore . ..

        } else 	if (finder.IsDirectory( )) { // recursively step down
            RemoveFiles(path,olderThan);
            RemoveDirectory(path);
        }
        else {

            DWORD length = finder.GetLength();

            TRACE("F %s c %ld a %ld w %ld size %ld \n",(const char *) path, creationTime.GetTime(),accessTime.GetTime(),writeTime.GetTime(),length);
            if (olderThan >0 ) {

                if (t < olderThan) {
                    if (RemoveFile(path))
                        fileSum += length;
                }


            } else {
                if (RemoveFile(path))
                    fileSum += length;
            }

        }


    }
    finder.Close();

    TRACE("%ld bytes deleted \n",(long) fileSum);

    return TRUE;
}
Esempio n. 6
0
int path_destroy(const char* inDirName)
{
#if defined(WIN32)
  char dirName[MAX_PATH];
  char* dirNamePtr = dirName;
  char ch;
  WIN32_FIND_DATA fd;
  HANDLE handle;

  if (*inDirName == 0)
    return 1;

  while (ch = *inDirName++) {
    if (ch == '/'  ||  ch == '\\')
      *dirNamePtr++ = '\\';
    else
      *dirNamePtr++ = ch;
  }
  if (dirNamePtr[-1] != '\\')
    *dirNamePtr++ = '\\';
  *dirNamePtr = 0;

  strcpy(dirNamePtr, "*.*");

  handle = FindFirstFile(dirName, &fd);
  *dirNamePtr = 0;

  if (handle != INVALID_HANDLE_VALUE)
  {
    do {
      if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
        int skipDir = fd.cFileName[0] == '.'  &&
          (fd.cFileName[1] == 0  ||  (fd.cFileName[1] == '.'  &&  fd.cFileName[2] == 0));
        if (!skipDir) {
          strcpy(dirNamePtr, fd.cFileName);
          strcat(dirNamePtr, "\\");
          if (!path_destroy(dirName)) {
            FindClose(handle);
            return 0;
          }
        }
      } else {
        strcpy(dirNamePtr, fd.cFileName);
        SetFileAttributes(dirName, FILE_ATTRIBUTE_ARCHIVE);
        if (!DeleteFile(dirName)) {
          FindClose(handle);
          return 0;
        }
      }
	} while (FindNextFile(handle, &fd));

    FindClose(handle);
  }

  *--dirNamePtr = 0;
  if (!RemoveDirectory(dirName))
    return 0;
#else
  char dirName[FILENAME_MAX];
  char* dirNamePtr;
  char ch;

  if (*inDirName == 0)
    return 1;

  dirNamePtr = dirName;

  while (ch = *inDirName++) {
    if (ch == '/'  ||  ch == '\\')
      *dirNamePtr++ = '/';
    else
      *dirNamePtr++ = ch;
  }
  if (dirNamePtr[-1] != '/')
    *dirNamePtr++ = '/';
  *dirNamePtr = 0;

  DIR* dirp = opendir(dirName);
  if (dirp)
  {
    struct dirent* dp;
    while ((dp = readdir(dirp)) != NULL) {
      strcpy(dirNamePtr, dp->d_name);
	  if (dp->d_type & DT_DIR) {
        int skipDir = dp->d_name[0] == '.'  &&  (dp->d_name[1] == 0  ||  (dp->d_name[1] == '.'  &&  dp->d_name[2] == 0));
        if (!skipDir) {
          strcat(dirNamePtr, "/");
          if (!path_destroy(dirName)) {
            closedir(dirp);
            return 0;
		  }
        }
      } else {
        if (unlink(dirName) == -1) {
          closedir(dirp);
          return 0;
        }
      }
    }
  }

  closedir(dirp);

  *--dirNamePtr = 0;
  if (rmdir(dirName) == -1)
    return 0;
#endif

  return 1;
}
Esempio n. 7
0
BOOL WINPROC EXPORT DlgRoomWhoAreYou (HWND hWnd,UINT wMsg,WPARAM wParam,LPARAM lParam)
{
	STRING	szTmp;
	WORD	wKey;
	int		iTmp;
    BOOL	bHandled = TRUE;
	int		iPtSize = 30;

	if (wMsg == WM_INITDIALOG)
	{
#ifdef _MAC	
		RECT rEdit;
#endif		
		DefRoomProc (hWnd, wMsg, wParam, lParam);

		if (LoadString (hInstAstral, IDS_FONT_NORMAL, szTmp, sizeof(szTmp)))
		{
			hDlgFont = (HFONT)NULL;
			hDlgFont = CreateFont (-iPtSize,		// Height
									0,				// Width
									0,				// Escapement
									0,				// Orientation
									0,				// Weight
									0,				// Italic
									0,				// Underline
									0,				// Strikeout
									0,				// Charset
									0,				// OutputPrecision
									0,				// ClipPrecision
									0,				// Quality
									0,				// PitchAndFamily
		  							(PSTR)szTmp);	// Typeface Name

			if (hDlgFont != NULL)
			{
				SendDlgItemMessage (hWnd, IDC_WHO_BUTTON1, WM_SETFONT, (WPARAM)hDlgFont, 0L);
				SendDlgItemMessage (hWnd, IDC_WHO_BUTTON2, WM_SETFONT, (WPARAM)hDlgFont, 0L);
				SendDlgItemMessage (hWnd, IDC_WHO_BUTTON3, WM_SETFONT, (WPARAM)hDlgFont, 0L);
				SendDlgItemMessage (hWnd, IDC_WHO_BUTTON4, WM_SETFONT, (WPARAM)hDlgFont, 0L);
				SendDlgItemMessage (hWnd, IDC_WHO_NEWBUTTON, WM_SETFONT, (WPARAM)hDlgFont, 0L);
				SendDlgItemMessage (hWnd, IDC_WHO_EDIT, WM_SETFONT, (WPARAM)hDlgFont, 0L);
			}
		}
		
		
#ifdef _MAC	
		// Make sure the edit control is exactly the same size as the radio button.
		// Without this hack, it is smaller on the mac.
		
		if (LoadString (hInstAstral, IDS_IM_NEW, szTmp, sizeof(szTmp)))
			SetDlgItemText (hWnd, IDC_WHO_EDIT, szTmp);

		GetClientRect(GetDlgItem(hWnd, IDC_WHO_NEWBUTTON), &rEdit);	
		SetWindowPos(
			GetDlgItem(hWnd, IDC_WHO_EDIT),
			NULL,
			0, 0,
			RectWidth(&rEdit),
			RectHeight(&rEdit),
			SWP_NOMOVE | SWP_NOZORDER);
#endif		
		
		// initially hide the edit control
    	ShowWindow (GetDlgItem(hWnd, IDC_WHO_EDIT), SW_HIDE);

		if (LoadString (hInstAstral, IDS_IM_NEW, szTmp, sizeof(szTmp)))
			SetDlgItemText (hWnd, IDC_WHO_NEWBUTTON, szTmp);

		DoInit (hWnd);

    	ShowWindow (GetDlgItem(hWnd, IDOK), SW_HIDE);
		fButtonHidden = FALSE;
		bHandled = TRUE;
	}
    else if (wMsg == WM_CLOSE)
    {
        AstralDlgEnd (hWnd,TRUE|2);
		bHandled = TRUE;
    }
    else if (wMsg == WM_COMMAND)
    {
		switch (wParam)
		{
			// Go To Room hotspot
			case HS_WHO:
				if (CheckUsername (hWnd))
				{
					DeleteObject (hDlgFont);
        			GoRoom (hInstAstral, RM_ARTROOM, FALSE);
				}
				bHandled = TRUE;
				break;

			// I'm New button
			case IDC_WHO_NEWBUTTON:
#ifndef _MAC	// This problem doesn't exist on the mac			
				if (! fNoUsers)	// hack for Windows focus problem
#endif				
				{
					CheckRadioButton (hWnd, IDC_WHO_BUTTON1,
					  IDC_WHO_NEWBUTTON, IDC_WHO_NEWBUTTON);
    				ShowWindow (GetDlgItem(hWnd, IDC_WHO_NEWBUTTON), SW_HIDE);
    				ShowWindow (GetDlgItem(hWnd, IDC_WHO_EDIT), SW_SHOW);

					if (LoadString (hInstAstral, IDS_YOUR_NAME, szTmp,
				  	sizeof(szTmp)))
						SetDlgItemText (hWnd, IDC_WHO_EDIT, szTmp);

					SetFocus (GetDlgItem (hWnd, IDC_WHO_EDIT));
					SendDlgItemMessage (hWnd, IDC_WHO_EDIT, EM_SETSEL, 0,
				  	  MAKELONG(0, -1) );
				}
				iButtonIndex = 4;
				fNoUsers = FALSE;
				bHandled = TRUE;
				fButtonHidden = TRUE;
				break;

			// Scroll names down
			case HS_WHO_UPARROW:
				if (iUserCount > 4)
				{
					iTmp = iUserIndex;
					if (iUserIndex > 0)
                    {
						iUserIndex--;
                    	ShowWindow (GetDlgItem(hWnd, HS_WHO_DNARROW), SW_SHOW);

						if (iUserIndex == 0)
                    		ShowWindow (GetDlgItem(hWnd, HS_WHO_UPARROW), SW_HIDE);
                    }
                    else
            			ShowWindow (GetDlgItem(hWnd, HS_WHO_UPARROW), SW_HIDE);

					if (iUserIndex != iTmp)
						UpdateButtons (hWnd, iUserIndex, iUserCount);
				}
				bHandled = TRUE;
				break;

			// Scroll names up
			case HS_WHO_DNARROW:
				if (iUserCount > 4)
				{
					iTmp = iUserIndex;
					if (iUserIndex < (iUserCount - 4))
                    {
						iUserIndex++;
                    	ShowWindow (GetDlgItem(hWnd, HS_WHO_UPARROW), SW_SHOW);

						if (iUserIndex +4 >= iUserCount)
                    		ShowWindow (GetDlgItem(hWnd, HS_WHO_DNARROW), SW_HIDE);
                    }
                    else
            			ShowWindow (GetDlgItem(hWnd, HS_WHO_DNARROW), SW_HIDE);

					if (iUserIndex != iTmp)
						UpdateButtons (hWnd, iUserIndex, iUserCount);
				}
				bHandled = TRUE;
				break;

			case IDC_WHO_BUTTON1:
				HandleButton (hWnd, 0);
        		bHandled = TRUE;
				// if they click twice on same control - validate and continue
				if ((iButtonIndex == 0) && (CheckUsername (hWnd)))
				{
					DeleteObject (hDlgFont);
        			GoRoom (hInstAstral, RM_ARTROOM, FALSE);
				}
				iButtonIndex = 0;
				break;

			case IDC_WHO_BUTTON2:
				HandleButton (hWnd, 1);
        		bHandled = TRUE;
				if ((iButtonIndex == 1) && (CheckUsername (hWnd)))
				{
					DeleteObject (hDlgFont);
        			GoRoom (hInstAstral, RM_ARTROOM, FALSE);
				}
				iButtonIndex = 1;
				break;

			case IDC_WHO_BUTTON3:
				HandleButton (hWnd, 2);
        		bHandled = TRUE;
				if ((iButtonIndex == 2) && (CheckUsername (hWnd)))
				{
					DeleteObject (hDlgFont);
        			GoRoom (hInstAstral, RM_ARTROOM, FALSE);
				}
				iButtonIndex = 2;
				break;

			case IDC_WHO_BUTTON4:
				HandleButton (hWnd, 3);
        		bHandled = TRUE;
				if ((iButtonIndex == 3) && (CheckUsername (hWnd)))
				{
					DeleteObject (hDlgFont);
        			GoRoom (hInstAstral, RM_ARTROOM, FALSE);
				}
				iButtonIndex = 3;
				break;

			case IDC_WHO_DELNAME:
				if (Control.CurrentUser[0] != 0)
				{
					if (! (GetNumberIniEntries() ))
					{
						if (GetUserNameByDir (Control.CurrentUser, szTmp))
						{
							DeleteUserName (szTmp);
							lstrcpy (szTmp, Control.WorkPath);
							lstrcat (szTmp, Control.CurrentUser);
#ifdef WIN32
							RemoveDirectory (szTmp);
#else
							_rmDir (szTmp);
#endif							
							clr ((LPTR)Control.CurrentUser, sizeof(Control.CurrentUser));
							DoInit (hWnd);
						}
					}
				}
        		bHandled = TRUE;
				break;

			case IDOK:
				bHandled = TRUE;
				if (CheckUsername (hWnd))
				{
					DeleteObject (hDlgFont);
       				GoRoom (hInstAstral, RM_ARTROOM, FALSE);
				}
				break;

			default:
        		bHandled = FALSE;
				break;
		}
    }
    else if (wMsg == WM_CHAR)
	{
		wKey = (WORD)lParam;
		if (wKey == VK_DELETE)
		{
			GetUserNameString (iUserIndex, szTmp);
		}
	}
    else
        bHandled = FALSE;

    if (! bHandled)
        bHandled = DefRoomProc (hWnd, wMsg, wParam, lParam);

    return bHandled;
}
Esempio n. 8
0
/*
 *	pgsymlink - uses Win32 junction points
 *
 *	For reference:	http://www.codeproject.com/KB/winsdk/junctionpoints.aspx
 */
int
pgsymlink(const char *oldpath, const char *newpath)
{
	HANDLE		dirhandle;
	DWORD		len;
	char		buffer[MAX_PATH * sizeof(WCHAR) + sizeof(REPARSE_JUNCTION_DATA_BUFFER)];
	char		nativeTarget[MAX_PATH];
	char	   *p = nativeTarget;
	REPARSE_JUNCTION_DATA_BUFFER *reparseBuf = (REPARSE_JUNCTION_DATA_BUFFER *) buffer;

	CreateDirectory(newpath, 0);
	dirhandle = CreateFile(newpath, GENERIC_READ | GENERIC_WRITE,
						   0, 0, OPEN_EXISTING,
			   FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, 0);

	if (dirhandle == INVALID_HANDLE_VALUE)
		return -1;

	/* make sure we have an unparsed native win32 path */
	if (memcmp("\\??\\", oldpath, 4))
		sprintf(nativeTarget, "\\??\\%s", oldpath);
	else
		strcpy(nativeTarget, oldpath);

	while ((p = strchr(p, '/')) != 0)
		*p++ = '\\';

	len = strlen(nativeTarget) * sizeof(WCHAR);
	reparseBuf->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
	reparseBuf->ReparseDataLength = len + 12;
	reparseBuf->Reserved = 0;
	reparseBuf->SubstituteNameOffset = 0;
	reparseBuf->SubstituteNameLength = len;
	reparseBuf->PrintNameOffset = len + sizeof(WCHAR);
	reparseBuf->PrintNameLength = 0;
	MultiByteToWideChar(CP_ACP, 0, nativeTarget, -1,
						reparseBuf->PathBuffer, MAX_PATH);

	/*
	 * FSCTL_SET_REPARSE_POINT is coded differently depending on SDK version;
	 * we use our own definition
	 */
	if (!DeviceIoControl(dirhandle,
	 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_ANY_ACCESS),
						 reparseBuf,
	reparseBuf->ReparseDataLength + REPARSE_JUNCTION_DATA_BUFFER_HEADER_SIZE,
						 0, 0, &len, 0))
	{
		LPSTR		msg;

		errno = 0;
		FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
					  NULL, GetLastError(),
					  MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
					  (LPSTR) &msg, 0, NULL);
#ifndef FRONTEND
		ereport(ERROR,
				(errcode_for_file_access(),
				 errmsg("could not set junction for \"%s\": %s",
						nativeTarget, msg)));
#else
		fprintf(stderr, _("could not set junction for \"%s\": %s\n"),
				nativeTarget, msg);
#endif
		LocalFree(msg);

		CloseHandle(dirhandle);
		RemoveDirectory(newpath);
		return -1;
	}

	CloseHandle(dirhandle);

	return 0;
}
Esempio n. 9
0
//Implementation of DeviceCtrl routine.
static DWORD FatDeviceCtrl(__COMMON_OBJECT* lpDrv,__COMMON_OBJECT* lpDev, __DRCB* lpDrcb)
{
	__COMMON_OBJECT*       pFindHandle = NULL;

	if((NULL == lpDev) || (NULL == lpDrcb))  //Invalid parameters.
	{
		goto __TERMINAL;
	}
	//Dispatch the request to appropriate routines according to control command.
	switch(lpDrcb->dwCtrlCommand)
	{
	case IOCONTROL_FS_CHECKPARTITION:
		return CheckPartition(lpDev,(__COMMON_OBJECT*)lpDrcb->lpInputBuffer) ? 1 : 0;
	case IOCONTROL_FS_FINDFIRSTFILE:
		pFindHandle = FindFirstFile((__COMMON_OBJECT*)lpDev,
			(CHAR*)lpDrcb->dwExtraParam1,
			(FS_FIND_DATA*)lpDrcb->dwExtraParam2);
		if(NULL == pFindHandle)  //Can not start the iterate.
		{
			return 0;
		}
		lpDrcb->lpOutputBuffer = (LPVOID)pFindHandle;
		return 1;
	case IOCONTROL_FS_FINDNEXTFILE:
		return FindNextFile((__COMMON_OBJECT*)lpDev,
			(__COMMON_OBJECT*)lpDrcb->lpInputBuffer,
			(FS_FIND_DATA*)lpDrcb->dwExtraParam2) ? 1 : 0;
	case IOCONTROL_FS_FINDCLOSE:
		FindClose((__COMMON_OBJECT*)lpDev,
			(__COMMON_OBJECT*)lpDrcb->lpInputBuffer);
		break;
	case IOCONTROL_FS_CREATEDIR:
		if(_CreateDirectory(lpDev,
			(LPSTR)lpDrcb->lpInputBuffer,
			0))
		{
			lpDrcb->dwStatus = DRCB_STATUS_SUCCESS;
			return 1;
		}
		else
		{
			lpDrcb->dwStatus = DRCB_STATUS_FAIL;
			return 0;
		}
		break;
	case IOCONTROL_FS_GETFILEATTR:
		lpDrcb->dwExtraParam2 = GetFileAttributes(
			lpDev,
			(LPCTSTR)lpDrcb->dwExtraParam1);
		lpDrcb->dwStatus = DRCB_STATUS_SUCCESS;
		return 1;
		break;
	case IOCONTROL_FS_DELETEFILE:
		if(DeleteFile(lpDev,
			(LPSTR)lpDrcb->lpInputBuffer))
		{
			lpDrcb->dwStatus = DRCB_STATUS_SUCCESS;
			return 1;
		}
		else
		{
			lpDrcb->dwStatus = DRCB_STATUS_FAIL;
			return 0;
		}
		break;
	case IOCONTROL_FS_REMOVEDIR:
		if(RemoveDirectory(lpDev,
			(LPSTR)lpDrcb->lpInputBuffer))
		{
			lpDrcb->dwStatus = DRCB_STATUS_SUCCESS;
			return 1;
		}
		else
		{
			lpDrcb->dwStatus = DRCB_STATUS_FAIL;
			return 0;
		}
		break;
	case IOCONTROL_FS_SETENDFILE:
		{
		if(SetEndOfFile(lpDev))
			{
				lpDrcb->dwStatus = DRCB_STATUS_SUCCESS;
				return 1;
			}
			else
			{
				lpDrcb->dwStatus = DRCB_STATUS_FAIL;
				return 0;
			}
		}
		break;
	default:
		break;
	}

__TERMINAL:
	return 0;
}
Esempio n. 10
0
int platform_removeDir(const char *path)
{
    return RemoveDirectory(path) ? -1 : 0;
}
Esempio n. 11
0
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
#endif
{
	hInst = hInstance;
	isWin64 = IsWindows64();
	
	GetVersionEx(&gOSVer);
	
	int nInstallVer = 0;
	
	wsprintf(gsTitle, L"ConEmu %s installer", CONEMUVERL);
	lstrcpyn(gsRunAsAdm, L"Run installer as administrator", countof(gsRunAsAdm));

	wchar_t szArg[MAX_PATH+1];
	LPCWSTR pszCmdToken = GetCommandLine();
	LPCWSTR pszCmdLineW = pszCmdToken;
	
	gsTempFolder[0] = 0;
	
	while (0 == NextArg(&pszCmdToken, szArg))
	{
		if (lstrcmp(szArg, L"/?") == 0 || lstrcmp(szArg, L"-?") == 0 || lstrcmp(szArg, L"-h") == 0
			|| lstrcmp(szArg, L"-help") == 0 || lstrcmp(szArg, L"--help") == 0)
		{
			MessageBox(NULL,
				L"Usage:\n"
				L"   ConEmuSetup [/p:x86[,adm] | /p:x64[,adm]] [<msi args>]\n"
				L"   ConEmuSetup [/e[:<extract path>]] [/p:x86 | /p:x64]\n"
				L"Example (run x64 auto update as administrator):\n"
				L"   ConEmuSetup /p:x64,adm /qr",
				gsTitle, MB_ICONINFORMATION);
			return 1;
		}
		
		if (*szArg == L'/')
		{
			if (szArg[1] == L'e' || szArg[1] == L'E')
			{
				gbExtractOnly = true;
				if (szArg[2] == L':' && szArg[3])
				{
					lstrcpyn(gsTempFolder, (szArg[3]==L'"') ? (szArg+4) : (szArg+3), countof(gsTempFolder));
				}
				continue;
			}
		
		    if (memcmp(szArg, L"/p:x", 4*sizeof(*szArg)) == 0)
		    {
		    	gbAlreadyAdmin = IsUserAdmin();
				if (lstrcmpi(szArg+4, L"86") == 0)
				{
					nInstallVer = Ver86;
				}
				else if (lstrcmpi(szArg+4, L"86,adm") == 0)
				{
					nInstallVer = Ver86;
					gbUseElevation = !gbAlreadyAdmin;
				}
				else if (lstrcmpi(szArg+4, L"64") == 0)
				{
					nInstallVer = Ver64;
				}
				else if (lstrcmpi(szArg+4, L"64,adm") == 0)
				{
					nInstallVer = Ver64;
					gbUseElevation = !gbAlreadyAdmin;
				}
			}
			else
				pszCmdToken = pszCmdLineW;
			break;
		}
		else if (*szArg == L'-')
		{
			pszCmdToken = pszCmdLineW;
			break;
		}
			
		pszCmdLineW = pszCmdToken;
	}
	

	if (!gbExtractOnly)
	{
		wchar_t szInstallPath[MAX_PATH+32];
		bool bInstalled;
		HKEY hk;
	
		lstrcpyn(gsMessage, L"Choose version to install", countof(gsMessage));
		
			szInstallPath[0] = 0; bInstalled = false;
			struct {HKEY hk; LPCWSTR path; LPCWSTR name; bool our;}
				Keys[] = {
					{HKEY_LOCAL_MACHINE,L"SOFTWARE\\ConEmu",L"InstallDir",true},
					{HKEY_LOCAL_MACHINE,L"SOFTWARE\\Far Manager",L"InstallDir"},
					{HKEY_LOCAL_MACHINE,L"SOFTWARE\\Far2",L"InstallDir"},
					{HKEY_LOCAL_MACHINE,L"SOFTWARE\\Far",L"InstallDir"},
				};
			for (size_t s = 0; s < countof(Keys); s++)
			{
				if (!RegOpenKeyEx(Keys[s].hk, Keys[s].path, 0, KEY_READ, &hk)
					|| !RegOpenKeyEx(Keys[s].hk, Keys[s].path, 0, KEY_READ|KEY_WOW64_32KEY, &hk))
				{
					wchar_t szPath[MAX_PATH+1] = {}; DWORD cbSize = sizeof(szPath)-2;
					LONG lRc = RegQueryValueEx(hk, Keys[s].name, NULL, NULL, (LPBYTE)szPath, &cbSize);
					RegCloseKey(hk);
					if (!lRc && *szPath)
					{
						bInstalled = Keys[s].our;
						lstrcpy(szInstallPath, szPath);
						cbSize = lstrlen(szInstallPath);
						if (szInstallPath[cbSize-1] == L'\\') szInstallPath[cbSize-1] = 0;
						break;
					}
				}
			}
			if (szInstallPath[0] == 0)
			{
				GetEnvironmentVariable(L"ProgramFiles", szInstallPath, MAX_PATH);
				int nLen = lstrlen(szInstallPath);
				lstrcat(szInstallPath, (nLen > 0 && szInstallPath[nLen-1] != L'\\') ? L"\\ConEmu" : L"ConEmu");
			}
			wsprintf(gsVer86, L"%s x86\n%s installation folder is\n%s", CONEMUVERL, bInstalled ? L"Current" : L"Default", szInstallPath);

			
		if (isWin64)
		{
			
				szInstallPath[0] = 0; bInstalled = false;
				struct {HKEY hk; LPCWSTR path; LPCWSTR name; bool our;}
					Keys[] = {
						{HKEY_LOCAL_MACHINE,L"SOFTWARE\\ConEmu",L"InstallDir_x64",true},
						{HKEY_LOCAL_MACHINE,L"SOFTWARE\\Far Manager",L"InstallDir_x64"},
						{HKEY_LOCAL_MACHINE,L"SOFTWARE\\Far2",L"InstallDir_x64"},
						{HKEY_LOCAL_MACHINE,L"SOFTWARE\\Far",L"InstallDir_x64"},
					};
				for (size_t s = 0; s < countof(Keys); s++)
				{
					if (!RegOpenKeyEx(Keys[s].hk, Keys[s].path, 0, KEY_READ|KEY_WOW64_64KEY, &hk))
					{
						wchar_t szPath[MAX_PATH+1] = {}; DWORD cbSize = sizeof(szPath)-2;
						LONG lRc = RegQueryValueEx(hk, Keys[s].name, NULL, NULL, (LPBYTE)szPath, &cbSize);
						RegCloseKey(hk);
						if (!lRc && *szPath)
						{
							bInstalled = Keys[s].our;
							lstrcpy(szInstallPath, szPath);
							cbSize = lstrlen(szInstallPath);
							if (szInstallPath[cbSize-1] == L'\\') szInstallPath[cbSize-1] = 0;
							break;
						}
					}
				}
				if (szInstallPath[0] == 0)
				{
					GetEnvironmentVariable(L"ProgramW6432", szInstallPath, MAX_PATH);
					int nLen = lstrlen(szInstallPath);
					lstrcat(szInstallPath, (nLen > 0 && szInstallPath[nLen-1] != L'\\') ? L"\\ConEmu" : L"ConEmu");
				}
				wsprintf(gsVer64, L"%s x64\n%s installation folder is\n%s", CONEMUVERL, bInstalled ? L"Current" : L"Default", szInstallPath);

			wsprintf(gsFull, L"%s\n\nPress `Yes` to install x64 version\nPress `No` to install x86 version", gsMessage);
		}
		else
		{
			gsVer64[0] = 0;
		}
	}
	else
	{
		wchar_t szPath[MAX_PATH+1];
		if (*gsTempFolder)
		{
			lstrcpy(szPath, gsTempFolder);
		}
		else
		{
			GetTempPath(countof(szPath) - 14, szPath);
			wchar_t* pszSubDir = szPath+lstrlen(szPath);
			lstrcpy(pszSubDir, L"ConEmu");
			pszSubDir += 6;
			lstrcpy(pszSubDir, CONEMUVERL);
		}
		
		lstrcpyn(gsMessage, L"Choose version to extract", countof(gsMessage));
		wsprintf(gsVer86, L"%s x86\nExtract installation files to\n%s", CONEMUVERL, szPath);
		wsprintf(gsVer64, L"%s x64\nExtract installation files to\n%s", CONEMUVERL, szPath);
		wsprintf(gsFull, L"%s\n\nPress `Yes` to extract x64 version\nPress `No` to extract x86 version\n\n%s", gsMessage, szPath);
	}
	
	if (nInstallVer == 0)
		nInstallVer = ChooseVersion(); // IDCANCEL/Ver86/Ver64
		
	if (nInstallVer != Ver86 && nInstallVer != Ver64)
		return 1;
	
	if (gbExtractOnly && *gsTempFolder)
	{
		CreateDirectory(gsTempFolder, NULL);
	}
	else
	{
		GetTempPath(countof(gsTempFolder) - 14, gsTempFolder);
		
		wchar_t* pszSubDir = gsTempFolder+lstrlen(gsTempFolder);
		lstrcpy(pszSubDir, L"ConEmu");
		pszSubDir += 6;
		lstrcpy(pszSubDir, CONEMUVERL);
		pszSubDir += lstrlen(pszSubDir);
		if (!CreateDirectory(gsTempFolder, NULL))
		{
			bool lbCreated = false;
			SYSTEMTIME st = {}; GetLocalTime(&st);
			for (int i = 0; i < 100; i++)
			{
				wsprintf(pszSubDir, L"_%02i%02i%02i%i", st.wHour, st.wMinute, st.wSecond, i);
				if (CreateDirectory(gsTempFolder, NULL))
				{
					lbCreated = true;
					break;
				}
			}
			if (!lbCreated)
			{
				return ReportError(10, L"Can't create temp folder\n%s", gsTempFolder);
			}
		}
	}

	wsprintf(gsMsiFile, L"%s\\ConEmu.%s.%s.msi", gsTempFolder, CONEMUVERL, (nInstallVer == Ver86) ? L"x86" : L"x64");
	wsprintf(gsCabFile, L"%s\\ConEmu.cab", gsTempFolder);
	
	bool lbNeedExe = false;
	if (!gbExtractOnly && gOSVer.dwMajorVersion >= 6)
		lbNeedExe = true;

	if (!lbNeedExe)
		gsExeFile[0] = 0;
	else
		wsprintf(gsExeFile, L"%s\\ConEmuSetup.exe", gsTempFolder);
	
	int iExpMsi = ExportFile(nInstallVer, gsMsiFile);
	int iExpCab = (iExpMsi == 0) ? ExportFile(CABFILE, gsCabFile) : -1;
	int iExpExe = (!lbNeedExe) ? 0 : (iExpCab == 0) ? ExportFile(EXEFILE, gsExeFile) : -1;
	if (iExpMsi != 0 || iExpCab != 0 || iExpExe != 0)
	{
		DeleteFile(gsMsiFile);
		DeleteFile(gsCabFile);
		if (*gsExeFile)
			DeleteFile(gsExeFile);
		RemoveDirectory(gsTempFolder);
		return (iExpMsi != 0) ? iExpMsi : iExpCab;
	}
	
	if (gbExtractOnly)
	{
		wchar_t szMessage[MAX_PATH*2];
		wsprintf(szMessage, L"Installation files was extracted successfully\n%s", gsTempFolder);
		MessageBox(NULL, szMessage, gsTitle, MB_ICONINFORMATION);
		return 0;
	}

	int iInstRc = 0;
	SHELLEXECUTEINFO sei = {sizeof(sei)};
	wchar_t* pszParms = NULL;
	sei.fMask = SEE_MASK_NOCLOSEPROCESS|/*SEE_MASK_NOASYNC*/0x00000100; //|/*SEE_MASK_NOZONECHECKS*/0x00800000;
	sei.lpVerb = L"open";
	if (gOSVer.dwMajorVersion<=5 || !gbUseElevation)
	{
		sei.lpFile = gsMsiFile;
		sei.lpParameters = pszCmdToken;
	}
	else
	{
		sei.lpFile = gsExeFile;
		int nMaxLen = lstrlen(gsMsiFile) + (pszCmdToken ? lstrlen(pszCmdToken) : 0) + 64;
		pszParms = (wchar_t*)malloc(nMaxLen*sizeof(wchar_t));
		wsprintf(pszParms, L"/i \"%s\" %s", gsMsiFile, pszCmdToken ? pszCmdToken : L"");
		sei.lpParameters = pszParms;
	}
	sei.lpDirectory = gsTempFolder;
	sei.nShow = SW_SHOWNORMAL;
	
	BOOL lbExecute = ShellExecuteEx(&sei);
	
	#if 0
	if (!lbExecute && lbNeedExe)
	{
		DWORD nErr = GetLastError();
		if (nErr == 1223)
		{
			// Отмена пользователем UAC, или правов не хватило?
			sei.fMask = SEE_MASK_NOCLOSEPROCESS|/*SEE_MASK_NOASYNC*/0x00000100; //|/*SEE_MASK_NOZONECHECKS*/0x00800000;
			sei.lpVerb = L"open";
			sei.lpFile = gsMsiFile;
			sei.lpParameters = pszCmdToken;
			sei.lpDirectory = gsTempFolder;
			sei.nShow = SW_SHOWNORMAL;
			
			lbExecute = ShellExecuteEx(&sei);
		}
	}
	#endif
	
	if (!lbExecute)
	{
		iInstRc = ReportError(20, L"Installer failed\n%s", gsMsiFile);
	}
	else
	{
		if (!sei.hProcess)
		{
			iInstRc = ReportError(21, L"Installer failed\n%s", gsMsiFile);
		}
		else
		{
			WaitForSingleObject(sei.hProcess, INFINITE);
			DWORD nCode = 0;
			SetLastError(0);
			//1602 - это похоже "Отмена" пользователем
			if (!GetExitCodeProcess(sei.hProcess, &nCode) || (nCode != 0 && nCode != 1602))
			{
				wchar_t szFormat[128]; wsprintf(szFormat, L"Installer failed\n%%s\nExitCode=%u", nCode);
				iInstRc = ReportError(100+nCode, szFormat, gsMsiFile);
			}
		}
	}
	
	DeleteFile(gsMsiFile);
	DeleteFile(gsCabFile);
	if (*gsExeFile)
		DeleteFile(gsExeFile);
	RemoveDirectory(gsTempFolder);
	
	return iInstRc;
}
Esempio n. 12
0
int _tmain(int argc, _TCHAR* argv[]) {
	int i;
	DWORD failures = 0;
	ULONGLONG size = 0;
	DWORD err;
	TCHAR *f;
	TCHAR sSize[64];
	
	parsed_args* args = parse_args(argc, argv);
	BOOL oneVolumeOnly = has_arg(args, TEXT("one-volume-only"), TEXT('\0'));

	PSID sid = NULL;
	PACL acl = NULL;
	BOOL takeownership;
	EXPLICIT_ACCESS ea[1];

	if (!args->file_count) {
		_ftprintf(stderr, TEXT("Usage: %s [options] file1 [file2 ...]\n\n"), args->program);
		_ftprintf(stderr, TEXT("  The files can be directories, files, or simple wildcards\n\n"));
		_ftprintf(stderr, TEXT("  Options:\n"));
		_ftprintf(stderr, TEXT("    --one-volume-only  do not delete files on other volumes when\n                       junctions/symbolic links/mount points are found"));
		return 1;
	}

	takeownership = EnableTakeOwnershipPriv();
	if (!takeownership) {
		_ftprintf(stderr, TEXT("! Failed to enable the Take Ownership privilege\n"));
		_ftprintf(stderr, TEXT("Make sure you are an Administrator or elevated\n"));
		_ftprintf(stderr, TEXT("We will still try to delete the files\n"));
	}
	sid = GetCurrentSID();
	if (!sid) {
		_ftprintf(stderr, TEXT("! Failed to get the current user's SID\n"));
		_ftprintf(stderr, TEXT("We will still try to delete the files\n"));
	} else {
		// Explicit Access: All Access
		ZeroMemory(&ea, 1*sizeof(EXPLICIT_ACCESS));
		ea[0].grfAccessPermissions = GENERIC_ALL;
		ea[0].grfAccessMode = SET_ACCESS;
		ea[0].grfInheritance = SUB_OBJECTS_ONLY_INHERIT;
		ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
		ea[0].Trustee.TrusteeType = TRUSTEE_IS_USER;
		ea[0].Trustee.ptstrName = (LPTSTR)sid;
		// Create the ACL
		err = SetEntriesInAcl(1, ea, NULL, &acl);
		if (err != ERROR_SUCCESS) {
			LogError(TEXT("SetEntriesInAcl"), err);
		}
	}

	files = vector_create(64);

	// Find all files to delete
	for (i = 0; i < args->file_count; i++) {
		DWORD attrib = GetFileAttributes(args->files[i]);
		if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY)) {
			vector_append(files, copyStr(args->files[i]));
			if (oneVolumeOnly && (attrib & FILE_ATTRIBUTE_REPARSE_POINT) && FileChangesVolume(args->files[i])) {
				continue;
			}
		}
		FindFiles(args->files[i], FALSE, oneVolumeOnly);
	}

	// Leave now if there is nothing to delete
	if (files->length == 0) {
		_tprintf(TEXT("No files found\n"));
		vector_destroy(files, TRUE);
		return 0;
	}

	// Correct security and delete files / directories
	for (i = files->length-1; i >= 0; i--) {
		WIN32_FILE_ATTRIBUTE_DATA attrib;
		BY_HANDLE_FILE_INFORMATION info;
		DWORD volumeSN = 0;
		f = (TCHAR*)files->x[i];
		if (!GetFileAttributesEx(f, GetFileExInfoStandard, &attrib))
			continue;
		CorrectSecurity(f, attrib.dwFileAttributes, takeownership, sid, acl, oneVolumeOnly);
		if (attrib.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
			if (!RemoveDirectory(f) && (err = DeleteWithSH(f)) != 0) {
				LogFileError(TEXT("Failed to delete folder"), f, err);
				failures++;
			}
		} else {
			if (!DeleteFile(f) && (err = DeleteWithSH(f)) != 0) {
				LogFileError(TEXT("Failed to delete file"), f, GetLastError());
				failures++;
			} else {
				size += attrib.nFileSizeLow;
				size += ((ULONGLONG)attrib.nFileSizeHigh) << 32;
			}
		}
	}

	// Show results
	if (size < 1000)			_sntprintf(sSize, 64, TEXT("%I64d bytes"), size);
	else if (size < 1000000)	_sntprintf(sSize, 64, TEXT("%.2f KB"), size / 1024.0);
	else if (size < 1000000000)	_sntprintf(sSize, 64, TEXT("%.2f MB"), size / 1024 / 1024.0);
	else						_sntprintf(sSize, 64, TEXT("%.2f GB"), size / 1024 / 1024 / 1024.0);
	_tprintf(TEXT("Deleted %d files (%s)\n"), files->length-failures, sSize);
	if (failures > 0)
		_tprintf(TEXT("Failed to delete %d files\n"), failures);

	// Cleanup
	vector_destroy(files, TRUE);
	LocalFree(acl);
	LocalFree(sid);
	free_parsed_args(args);

	return 0;
}
Esempio n. 13
0
int Q_rmdir (const char *path)
{
	if (RemoveDirectory(path) != 0)
		return 0;
	return -1;
}