글
(WinAPI) 디렉터리 제어 응용
출처 : http://blog.daum.net/studiocoma/6521408
Win32 API가 제공하는 CreateDirectory 함수의 응용.
API CreateDirectory의 경우 c:\1\2\3을 만들때 c:\1\2가 이미 존재하지 않으면 실패한다. -_-
이를 보완하고(상위폴더부터 주구장창 만들어 낸다;) 경로에 파일명까지 포함되어 있어도 폴더만 만들도록 해봤다.
- 말은 거창(?)한데 그냥 문자열 파싱해서 CreateDirectory를 반복 호출한다;;
BOOL _CreateDirectory( LPCTSTR lpszPath )
{
TCHAR szPathBuffer[MAX_PATH];
size_t len = _tcslen( lpszPath );
for ( size_t i = 0 ; i < len ; i++ )
{
szPathBuffer[i] = *( lpszPath + i );
if ( szPathBuffer[i] == _T('\\') || szPathBuffer[i] == _T('/') )
{
szPathBuffer[i + 1] = NULL;
if ( ! PathFileExists( szPathBuffer ) )
{
if ( ! ::CreateDirectory( szPathBuffer, NULL ) )
{
if ( GetLastError() != ERROR_ALREADY_EXISTS )
return FALSE;
}
}
}
}
return TRUE;
}
-----------------------------------------------------------------------------------------
CFileFind fileFinder;
if(!fileFinder.FindFile(".\\simple\\MyMenu.mdb"))
{
CreateDirectory(".\\simple", NULL);
CopyFile(".\\MyMenu.mdb", ".\\simple\\MyMenu.mdb", TRUE);
}
부모디렉토리없어도 디렉토리 생성하기, 디렉토리에 파일있어도 하위디렉토리까지 모든파일 삭제하기
출처 : http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=51&MAEULNo=20&no=7293&ref=7293
#include <windows.h>
#include <stdio.h>
#include <string>
using namespace std;
/*
기존 디렉토리가 있을경우 안만들어지고 없으면 만든다. 부모디렉토리가 없어도 생성가능
*/
void CreateDir(char* Path)
{
char DirName[256]; //생성할 디렉초리 이름
char* p = Path; //인자로 받은 디렉토리
char* q = DirName;
while(*p)
{
if (('\\' == *p) || ('/' == *p)) //루트디렉토리 혹은 Sub디렉토리
{
if (':' != *(p-1))
{
CreateDirectory(DirName, NULL);
}
}
*q++ = *p++;
*q = '\0';
}
CreateDirectory(DirName, NULL);
}
/*
하위디렉토리를 제외한 해당 디렉토리 모든 파일들을 제거
*/
void DeleteAllFiles(char* folderPath)
{
char fileFound[256];
WIN32_FIND_DATA info;
HANDLE hp;
sprintf(fileFound, "%s\\*.*", folderPath);
hp = FindFirstFile(fileFound, &info); //디렉토리에 파일이 있는지 첫번째 파일만.
do
{
sprintf(fileFound,"%s\\%s", folderPath, info.cFileName);
DeleteFile(fileFound);
}while(FindNextFile(hp, &info)); //다른 파일이 있을때 까지
FindClose(hp);
}
/*
해당 하는 디렉토리에 파일이 존재해도 디렉토리가 비어있지 않아도 지울수 있다 .
*/
void EmptyDirectory(char* folderPath)
{
char fileFound[256];
WIN32_FIND_DATA info;
HANDLE hp;
sprintf(fileFound, "%s\\*.*", folderPath);
hp = FindFirstFile(fileFound, &info); //디렉토리에 파일이 있는지 첫번째 파일만.
do
{
if (!((strcmp(info.cFileName, ".")==0)||(strcmp(info.cFileName, "..")==0)))
{
if((info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)==FILE_ATTRIBUTE_DIRECTORY) //Sub디렉토리가 존재하는경우
{
string subFolder = folderPath;
subFolder.append("\\");
subFolder.append(info.cFileName);
EmptyDirectory((char*)subFolder.c_str()); /// {return (_Ptr == 0 ? _Nullstr() : _Ptr); }
RemoveDirectory(subFolder.c_str());
}
else
{
sprintf(fileFound,"%s\\%s", folderPath, info.cFileName);
BOOL retVal = DeleteFile(fileFound);
}
}
}while(FindNextFile(hp, &info));
FindClose(hp);
}
-----------------------------------------------------------------------------------------
CreateDirectory 에서 폴더 접근 권한 바꾸기
출처 : http://ktr0.egloos.com/757379
Windows API 를 보면 CreateDirectory 라는 함수가 있다.
CreateDirectory("c:\aaa",NULL);
위와 같은 방법으로 첫번째 파라메터에 폴더 이름을 써 주고
두번째 파라메터에 NULL 을 써 주는 경우가 많다.
두 번째 파라메터는 사실 보안에 대한 파라메터이다.
PSECURITY_ATTRIBUTE 형의 변수가 들어가는데, NULL 이면 부모 폴더의
값을 그대로 가져온다.
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;
PSID pEveryoneSID = NULL;
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
EXPLICIT_ACCESS ea[2];
PACL pacl = NULL;
if(!AllocateAndInitializeSid(&SIDAuthWorld,1, SECURITY_WORLD_RID,0,0,0,0,0,0,0,&pEveryoneSID))
{
AfxMessageBox("Fail to get Everyone SID!!!",0,0);
return;
}
ZeroMemory(&ea, 2*sizeof(EXPLICIT_ACCESS));
ea[0].grfAccessPermissions = GENERIC_ALL;
ea[0].grfAccessMode = SET_ACCESS;
ea[0].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea[0].Trustee.ptstrName = (LPTSTR) pEveryoneSID;
SetEntriesInAcl(1,ea, NULL, &pacl);
InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE,pacl , FALSE);
//SetSecurityDescriptorSacl(&sd, TRUE,pacl , FALSE);
sa.nLength = sizeof (SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = &sd;
sa.bInheritHandle = TRUE;
::CreateDirectory(sysDirBuffer_tmp,&sa);
if(pEveryoneSID){
FreeSid(pEveryoneSID);
}
if(pacl){
LocalFree(pacl);
}
위의 예가 바로 CreateDirectory 함수에서 SECURITY_ATTRIBUTE 값을 가지고
폴더에 모든 ACCESS 권한을 주는 예제이다.
http://www.tipssoft.com/bulletin/board.php?bo_table=QnA&wr_id=380&page=392
GetCurrentDirectory 함수 : 현재의 작업 디렉토리를 얻어온다.
SetCurrentDirectory 함수 : 작업디렉토리의 경로를 셋팅한다.
일반적으로 작업디렉토리는 파일이 실행된 경로가 지정됩니다.
아래는 작업디렉토리의 변경이 일어나는 대표적인 예인 CFileDialog 대화상자를 이용한 경우입니다
참고하시면 될 듯 싶습니다.
char path[MAX_PATH] = {0};
// 현재의 작업디렉토리를 저장한다.
GetCurrentDirectory(MAX_PATH, path);
// CFileDialog 를 Open 모드로 생성한다.
CFileDialog dlg(TRUE);
if(dlg.DoModal()==IDOK){
// 사용자가 폴더를 옮겨가며 특정 파일을 지정
// 이경우 작업폴더가 변경됨.
CString str = dlg.GetFileName();
//얻어온 파일과 관련된 코드 추가..............
// 이전에 저장했던 작업디렉토리 경로를 되돌려 셋팅
SetCurrentDirectory(path);
}
=============================================
Directory 컨트롤에 관하여 좋은 응용 예제를 모아놓은 블로그(http://blog.naver.com/dolicom/10096040743)에서 관련된 내용을 퍼왔다.
위의 응용 예제도 나쁘지 않지만, CreateDirectory 를 사용하여 디렉터리 트리를 구성할 때에는 CreateDirectory() 보다는 SHCreateDirectory / SHCreateDirectoryEx() 를 사용하는 것이 훨씬 편하다.
SHCreateDirectoryEx(NULL, "C:\\a\\b\\", NULL);
이런식으로만 하면 a 폴더가 없더라도 a\b 폴더 둘 다 만들어지기 때문이다. 해당 함수를 쓰기 위해서는 Shlobj.h 를 포함시켜야 한다.
SHCreateDirectoryEx : http://msdn.microsoft.com/en-us/library/windows/desktop/bb762131(v=vs.85).aspx
SHSHFileOperation function : http://msdn.microsoft.com/en-us/library/windows/desktop/bb762164(v=vs.85).aspx
'IT/Programming > WinAPI' 카테고리의 다른 글
(WinAPI/MFC) GUI 프로그래밍을 하면서 콘솔을 임의로 띄워 테스트하기 (0) | 2013.10.17 |
---|---|
(WinAPI) editbox 에 줄바꿈 삽입이 안될 때 (0) | 2013.10.16 |
TreeView CommonController 사용시 주의할 점 (0) | 2013.09.06 |
(WinAPI) 파일/폴더 경로 조작과 관련된 유용한 함수 리스트 (0) | 2013.07.10 |
(WinAPI) 문자열 함수(멀티바이트->유니코드->TCHAR) (0) | 2013.07.08 |