2008/07/30

Vista에서 Samba 서버 로그인이 안되는 문제...

회사 공유서버를 리눅스기반으로 하여 Samba 서버로 운영을 하고 있는데 요 근래 하나 둘 늘어나는 Vista 사용자들이 서버에 접속을 할 수 없다고 하여 확인을 해 보았다.

이 문제는 Vista에서 네트웍 접속시 기본 프로토콜로 NTLMv2 protocol를 사용하는데 Samba에서 이 프로토콜을 지원하지 않고 있기 때문이였다.

Vista 설정에서 보안 설정을 변경해 주면 된다.

우선 Win + R 단축키로 나타난 실행창에 secpol.msc 를 실행하여 로컬 보안 정책을 실행하여 보안설정의 로컬정책 안에 "네트워크 보안: LAN Manager 인증 수준"을 아래와 같이"LM 및 NTLM 보내기 - 협상되면 NTLMv3세션 보안 사용"로 변경하면 된다.

굿모닝 팝스 mp3 재생 및 다운로더 v6

사용자 삽입 이미지

이번 버전에서 바뀐점.

    - 캡션바에 최소화 버튼 활성화
    - 실행파일을 UPX 3.03 으로 압축

다운로드

최신버전 다운로드

Original Post : http://neodreamer-dev.tistory.com/131

2008/07/25

C++ Builder 용 SQLite Library 파일 만들기...

SQLite DLL을 다운로드 받으면 sqlite3.dll 과 sqlite3.def 파일이 있다.

그 중에 dll 파일에서 C++ Builder 에서 사용할 library 파일을 만들 수 있다.

이때 사용하는 프로그램은 Codegear 사에서 제공하는 ImpLib 라는 프로그램을 사용하면 된다.

sqlite3.dll 이 위치한 곳에서 아래 명령을 수행하면 sqlite3.lib 파일이 생성된다.

   > IMPLIB -a sqlite3.lib sqlite3.dll

이제 만들어진 sqlite3.lib를 원하는 프로젝트에 포함시키면 C++ Builder 에서도 작고 강력한 SQLite 를 사용할 수 있다.

프로그래밍 방법은 지난 포스팅을 참고하면 된다. 실 사용은 C++ Builder나 Visual C++ 이나 크게 차이가 없다.

2008/07/23 - [Dev Story/Tips] - Visual C++ 2005 에서 간단하게 SQLite Database 사용하기
 


C++ Builder 용 Library 파일

2008/07/24

C++ 코드로 SQLite v3 질의결과 row 단위로 컨트롤하기

정확히 어느 버전부터 지원을 하는지는 모르겠지만 sqlite v3 이후부터는 sqlite3_exec 에 의한 질의방식 외에 보다 더 자세히 데이터를 컨트롤 할 수 있는 방법을 지원한다.

방법은 아래 함수를 이용해서 할 수 있다.
    * sqlite3_prepare()
    * sqlite3_step()
    * sqlite3_column()
    * sqlite3_finalize()

prepared statement 를 이용하는 방법으로 sqlite3_prepare 함수로 prepared statement 를 수행하고 sqlite3_step 함수를 이용해서 한 row씩 진행하면서 sqlite3_column 함수를 이용하여 각각의 column 에 접근하는 방법이다. 모든 수행을 마치고 sqlite3_finalize 로 마무리 하면 된다.



    sqlite3* pSQLite3 = NULL;
sqlite3_stmt* pStmt = NULL;

int rst = sqlite3_open( "test.db", &pSQLite3 );

if ( rst )
{
TRACE( "Can't open database: %s\n", sqlite3_errmsg( pSQLite3 ));

sqlite3_close( pSQLite3 );
pSQLite3 = NULL;
}
else
{
const char szQuery[1024] = "SELECT * FROM MEMBER";
const char* szChar;

if ( sqlite3_prepare( pSQLite3, szQuery, 1024, &pStmt, &szChar )
== SQLITE_OK )
{
int nRow = sqlite3_data_count( pStmt );
TRACE( "sqlite3_data_count() : %d\n", nRow );

int nCol = sqlite3_column_count( pStmt );
TRACE( "sqlite3_column_count() : %d\n", nCol );

const char* col1name = sqlite3_column_name( pStmt, 0 );
const char* col2name = sqlite3_column_name( pStmt, 1 );

int nRowCnt = 0;
while ( sqlite3_step( pStmt ) == SQLITE_ROW )
{
++nRowCnt;

const unsigned char* col1 = sqlite3_column_text( pStmt, 0 );
const unsigned char* col2 = sqlite3_column_text( pStmt, 1 );

TRACE( "ROW %d: %s => %s, %s => %s \n",
nRowCnt, col1name, col1, col2name, col2 );
}
}

sqlite3_finalize( pStmt );

sqlite3_close( pSQLite3 );
pSQLite3 = NULL;
}


데모프로젝트

2008/07/23

Visual C++ 2005 에서 간단하게 SQLite Database 사용하기

우선 SQLite 사이트에서 윈도우용 DLL 파일과 소스 파일을 다운 받는다.

SQLite 3.6.0 Source 
SQLite 3.6.0 DLL    

다운로드 받은 파일들을 프로젝트의 임의의 폴더에 풀어 놓는다.
압축을 풀어놓은 파일들

압축을 풀어놓은 파일들


시작 메뉴의 "Visual Studio 2005 명령 프롬프트 열기"를 실행하여 도스프롬프트창을 열고 다운로드 받아서 압축을 풀어놓은 폴더로 이동하여 다음 명령을 수행하여 프로젝트에 사용할 .lib파일을 생성한다.

>LIB /DEF:sqlite3.def /MACHINE:x86
Library 생성 화면

Library 생성 화면

작업 후 파일 목록

작업 후 파일 목록


프로젝트 속성페이지의 C/C++ 항목의 추가 포함디렉토리와 링커 함목의 추가 라이브러리 디렉토리에 위에서 작업한 디렉토리의 경로를 입력해 주고 링커 함목의 추가 종속성에 위에서 만들어진 Library 파일인 sqlite3.lib 를 추가해 주면 프로젝트 설정은 끝이다.

이제 SQLite 에 접속하여 작업을 할 클래스 헤더파일에 "sqlite3.h" 파일을 포함시키고 callback 함수를 선언해 준다.

SQLite3 에서 질의를 하면 리턴받을 데이터가 있을경우 callback 함수를 호출하여 데이터를 넘겨주기때문에 callback 함수를 작성해 주어야 한다.

#include "sqlite3.h"

static int callback(void *NotUsed, int argc, char **argv, char **azColName)
{
int i;
for( i = 0; i < argc; i++)
{
TRACE("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
};


그리고 소스 파일에서 작업을 하면 된다.

sqlite3 *pSQLite3 = NULL; // SQLite DB 객체 저장 변수
char *szErrMsg = NULL; // Error 발생시 메세지를 저장하는 변수

// 데이터베이스 열기 : 파일이 존재하지 않으면 생성한다.
int rst = sqlite3_open( "test.db", &pSQLite3);

if ( rst )
{
TRACE( "Can't open database: %s\n", sqlite3_errmsg( pSQLite3 ));

sqlite3_close( pSQLite3 );
pSQLite3 = NULL;
}
else
{
TRACE("Database opened!!\n");

// 테이블 생성
rst = sqlite3_exec(pSQLite3,
"CREATE TABLE member ( name TEXT(20), age INTEGER )",
callback, 0, &szErrMsg);

// 데이터 삽입
rst = sqlite3_exec(pSQLite3,
"INSERT INTO member ( name, age ) values ( 'andy', 20 )",
callback, 0, &szErrMsg);

// 데이터 질의
rst = sqlite3_exec(pSQLite3,
"SELECT * FROM member",
callback, 0, &szErrMsg);
}

//객체 해제
sqlite3_free( szErrMsg );
sqlite3_close( pSQLite3 );


위 코드를 수행한 후의 출력창
출력창 내용

출력창 내용

데모 프로젝트




Original Post : http://neodreamer-dev.tistory.com/128

Access를 대체할 강력한 로컬 데이터베이스 엔진 sqlite 3



Access 데이터베이스를 대체할 만한 데이터베이스 엔진을 찾다가 발견한 녀석이다.



Access 처럼 네트웍을 지원하지는 않지만 단일 실행로 실행이 되며 데이터베이스 파일도 단일 파일로 관리가 되어 이동성에도 좋다.



그 외에도 Transactions, SQL92, Cross-platform 그리고 간단하고 쉬운 API도 제공한다.

명령행 사용 화면

단일 실행파일에 의한 데이터베이스 사용



기본으로 제공하는 데이터베이스 엔진은 500KB 정도의 단일 실행파일로 커맨드라인 인터페이스만을 제공하지만 무료로 사용할 수 있는 GUI 툴도 있다.
SQLiteSpy

SQLite GUI for Windows


SQLiteSpy 를 이용하여 test.db에 접속한 화면

SQLiteSpy 를 이용하여 test.db에 접속한 화면


SQLite3 website
SQLiteSpy website
Original Post :
http://neodreamer-dev.tistory.com/127

2008/07/22

Microsoft 의 MSDN Magazine 이 안보일때...

Microsoft 사에서 배포하는 MSDN Magazine 을 다운로드하여 보면 내용을 보여주는 화면에 "작업 취소"나 "페이지를 표시할 수 없습니다"란 페이지만 나오고 내용을 볼 수 없는 경우가 생기는데..

사용자 삽입 이미지

이때 파일의 속성중 보안에 관련된 사항을 변경해 주면 볼 수 있다.
사용자 삽입 이미지

속성 페이지의 보안 부분에 차단 해제를 하고 도움말 파일을 다시 열면 정상적으로 볼 수 있다.
사용자 삽입 이미지

사실 이 내용은 MSDN Magazine 배포 페이지에서도 확인 할 수 있는 내용이다

Original Post : http://neodreamer-dev.tistory.com/126

2008/07/17

명령행 파라메터 읽어오기

C++ 윈도우즈 프로그래밍에서 명령행 파라메터를 가져오기 위해서는 __argc, __argv 를 이용한다.

이 외에 이번 포스팅에서 소개할 방법은 API를 활용하는 방법이다.

아래의 API를 사용하게되면 UNICODE 의 경우에도 별다른 작업없이 파라메터를 사용할 수 있다.

명령행 문자열을 가져오는 함수
    LPWSTR WINAPI GetCommandLineW(void);

이 함수를 실행하면 경로를 포함한 프로그램 이름과 명령행 파라메터를 문자일로 반환한다.


명령행 문자열을 문자열 배열로 변환하는 함수
LPWSTR *CommandLineToArgvW(      
    LPCWSTR lpCmdLine,
    int *pNumArgs
);

이 함수는 명령행 문자열과 파라메터 개수를 저장을 정수형 포인터를 받아 명령행 문자열을 문자열 배열형태로 바꿔주고 이때 문자열 배열 개수를 넘겨준 포인터 변수에 할당한다.
MFC 에서는 그냥 사용하면 되지만 C++ Builder 에서는 ShellApi.h 를 포함시켜줘야한다.

간단한 예를 보는 것이 이해가 빠를 것이다.

    // 예) 모든 파라메터 출력하기

LPWSTR *szArglist;
int nArgs;
int i;

szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
if( NULL == szArglist )
{
wprintf(L"CommandLineToArgvW failed\n");
}
else for( i = 0; i < nArgs; i++ ) TRACE("%d: %ws\n", i, szArglist[i]);

LocalFree(szArglist);



MSDN : GetCommandLine Function
MSDN : CommandLineToArgvW Function

Original Post : http://neodreamer-dev.tistory.com/125

레지스트리 파일 (.reg) 코딩으로 병합하기

Registry 파일(*.reg)을 병합하는 코드는 regedit 명령을 이용하면 된다.

regedit 명령의 스위치중 /s 이용하면 확인 대화상자가 나오지 않고 병합된다.

    #include <io.h>

char szRegFile[MAX_PATH] = "DefaultUI.reg\0";

if ( _access( szRegFile, 0 ) == 0 )
{
char szCmd[MAX_PATH];
strcpy_s( szCmd, MAX_PATH, "REGEDIT /s ");
strcat_s( szCmd, MAX_PATH, szRegFile );

WinExec( szCmd, SW_HIDE );
return;
}

Original Post : http://neodreamer-dev.tistory.com/124

2008/07/12

[XP] 로그인 화면에서 계정 숨기기

사용자 삽입 이미지


XP의 로그인 화면은 원하는 계정을 선택하여 로그인 할 수 있도록 계정 리스트가 나온다.

하지만 이 리스트에서 숨겨놓고 싶은 계정이 있어 이를 숨기려 한다.

숨겨진 계정으로 로그인을 하기 위해서는 Ctrl + Alt + Del 조합키를 이용하여 클래식 Login 화면으로 직접 타이핑해서 로그인을 하면 된다.

로그인 창에서 계정 감추기

레지스트리 편집기로 아래 위치로 이동한다.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList

위의 레지스트리 위치에 REG_DWORD 값을 추가하고 이름으로 감추고픈 계정으로 하고 값을 0으로 설정한다.

다시 부팅을 하면 로그인 화면에서 계정이 사라진 것을 확인할 수 있다

Original Post : http://neodreamer-dev.tistory.com/123

2008/07/11

유니코드와 아스키코드간의 변환 함수

MySQL++ 라이브러리 관련되어 테스트를 해보다 보게된 함수이다.

함수 스택 버퍼를 사용하는 W2A, A2W 보다 간단하게 함수를 만들어 사용하는게 메모리 운영면에서 여러모로 좋다.


//// ToUCS2 ////////////////////////////////////////////////////////////
// Convert a C string in UTF-8 format to UCS-2 format.

bool CExampleDlg::ToUCS2(LPTSTR pcOut, int nOutLen, const char* kpcIn)
{
if (strlen(kpcIn) > 0) {
// Do the conversion normally
return MultiByteToWideChar(CP_UTF8, 0, kpcIn, -1, pcOut,
nOutLen) > 0;
}
else if (nOutLen > 1) {
// Can't distinguish no bytes copied from an error, so handle
// an empty input string as a special case.
_tccpy(pcOut, _T(""));
return true;
}
else {
// Not enough room to do anything!
return false;
}
}


//// ToUTF8 ////////////////////////////////////////////////////////////
// Convert a UCS-2 multibyte string to the UTF-8 format.

bool CExampleDlg::ToUTF8(char* pcOut, int nOutLen, LPCWSTR kpcIn)
{
if (_tcslen(kpcIn) > 0) {
// Do the conversion normally
return WideCharToMultiByte(CP_UTF8, 0, kpcIn, -1, pcOut,
nOutLen, 0, 0) > 0;
}
else if (nOutLen > 0) {
// Can't distinguish no bytes copied from an error, so handle
// an empty input string as a special case.
*pcOut = '\0';
return true;
}
else {
// Not enough room to do anything!
return false;
}
}


Original Post : http://neodreamer-dev.tistory.com/122

2008/07/03

리눅스 시스템 정보 확인하기

시스템 정보 : uname -a
Linux server 2.4.18-4 #1 SMP Thu Aug 22 18:36:08 KST 2002 i686 unknown


CPU 정보 : cat /proc/cpuinfo
CPU 정보 : cat /proc/cpuinfo
processor       : 0
vendor_id       : AuthenticAMD
cpu family      : 15
model           : 12
model name      : AMD Sempron(tm) Processor 2800+
stepping        : 2
cpu MHz         : 1607.431
cache size      : 256 KB
fdiv_bug        : no
hlt_bug         : no
f00f_bug        : no
coma_bug        : no
fpu             : yes
fpu_exception   : yes
cpuid level     : 1
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov
pat pse36 clflush mmx fxsr sse sse2 syscall mmxext lm 3dnowext 3dnow
bogomips        : 3204.71


메모리 정보 : free -m
             total       used       free     shared    buffers     cached
Mem:           438        433          5          0         22        371
-/+ buffers/cache:         39        399
Swap:         2047          1       2046


파티션 정보 : fdisk -l
Disk /dev/hdc: 255 heads, 63 sectors, 19457 cylinders
Units = cylinders of 16065 * 512 bytes

   Device Boot    Start       End    Blocks   Id  System
/dev/hdc1   *         1      6374  51199123+  83  Linux
/dev/hdc2          6375     12748  51199155   83  Linux
/dev/hdc3         12749     19457  53890042+  83  Linux

Disk /dev/hda: 255 heads, 63 sectors, 19457 cylinders
Units = cylinders of 16065 * 512 bytes

   Device Boot    Start       End    Blocks   Id  System
/dev/hda1   *         1      1958  15727603+  83  Linux
/dev/hda2          1959      4554  20852370   83  Linux
/dev/hda3          4555     12338  62524980   83  Linux
/dev/hda4         12339     19457  57183367+   f  Win95 Ext'd (LBA)
/dev/hda5         12339     17527  41680611   83  Linux
/dev/hda6         17528     19456  15494661   82  Linux swap


스왑 파티션 정보 : swapon -s
Filename                        Type            Size    Used    Priority
/dev/hda6                       partition       2097136 1116    -1


디스크 사용 상태 : df -m
Filesystem           1M-blocks      Used Available Use% Mounted on
/dev/hda1                15118      6437      7913  45% /.....
/dev/hdc1                49214        33     46681   1% /.......
/dev/hdc3                51801     32514     16656  67% /...
/dev/hdc2                49214      2583     44131   6% /..
/dev/hda2                20043     10935      8090  58% /..
/dev/hda3                60101     55653      1395  98% /...
/dev/hda5                40065     34463      3567  91% /...
none                       219         0       219   0% /...
Original Post : http://neodreamer-dev.tistory.com/120

2008/07/02

문자형식 변경하기. UNICODE <-> ASCII

Visual Studio 2005 부터는 프로젝트의 기본 설정이 Unicode 기반으로 설정되어 있다.

따라서 문자열 대입시에 신경을 좀 더 써 주어야 한다.

간단하게 UNICODE 를 ASCII 코드로 바꾸는 일은 USES_CONVERSION; 매크로를 활용하면 쉽다.

변경하고자 하는 위치에 USES_CONVERSION; 을 입력하고 입맛에 맛는 매크로 함수를 호출하기만 하면 된다.


    USES_CONVERSION;

// Unicode 를 Ascii 로 변환 하고자 할 경우
W2A(LPWSTR), T2A(LPWSTR)

// Ascii 를 Unicode로 변경하고자 하는경우
A2W(LPSTR), A2T(LPSTR)

// MSDN 의 예제
//Example 1
// Convert LPCWSTR to LPCSTR.
void ExampleFunctionW( LPCWSTR pszW )
{
// Create an instance of CW2A, called pszA,
// and initialize it with pszW.
CW2A pszA( pszW );
// pszA works like an LPCSTR, and can be used thus:
ExampleFunctionA( pszA );
// Note: pszA will become invalid when it goes out of scope.
}

// Example 2
// Use a temporary instance of CW2A.
void ExampleFunctionW( LPCWSTR pszW )
{
// Create a temporary instance of CW2A,
// and initialize it with pszW.
ExampleFunctionA( CW2A( pszW ) );
// Note: the temporary instance becomes invalid
// after the execution of the statement above.
}

// Example 3
// Incorrect use of conversion macros.
void ExampleFunctionW( LPCWSTR pszW )
{
// Create a temporary instance of CW2A,
// save a pointer to it and then delete
// the temportary instance.
LPCSTR pszA = CW2A( pszW );
// The pszA in the following line is an invalid pointer,
// as the instance of CW2A has gone out of scope.
ExampleFunctionA( pszA );
}

아주 간편해서 좋은데 문제점을 안고 있는 방법이다. 왜 그런지는 자세히 파악이 되지 않았지만 위의 매크로 함수들은 메모리 활용면에서 비효율적인 문제가 있다고 한다. 간단하게 사용하는건 무리가 없는데 한번에 많은 수(10000번이상)의 변환에 이용하게되면 문제가 발생하기도 하였다.
실제로 32비트 프로젝트에서 아무런 문제가 발생하지 않았는데 이를 64비트로 변환시에 위의 함수를 사용하는 곳에서 문제가 발생하였다.

그래서 API를 활용하는 방법으로 바꾸어 사용을 하였다.
API를 이용한 문자형식 변경은 다음 두 함수를 이용하는 것이다.

    // Ascii 를 Unicode 로 변환할 경우
int MultiByteToWideChar(
UINT CodePage,
DWORD dwFlags,
LPCSTR lpMultiByteStr,
int cbMultiByte,
LPWSTR lpWideCharStr,
int cchWideChar
);

// Unicode를 Ascii 로 변환할 경우
int WideCharToMultiByte(
UINT CodePage,
DWORD dwFlags,
LPCWSTR lpWideCharStr,
int cchWideChar,
LPSTR lpMultiByteStr,
int cbMultiByte,
LPCSTR lpDefaultChar,
LPBOOL lpUsedDefaultChar
);


사용방법.
 
// Ascii 를 Unicode 로 변환할 경우
char szSource[1024] = "Sample Ascii string";
WCHAR wszBuf[1024];
int nBufSize = 1024;

MultiByteToWideChar( CP_ACP, 0, szSource, -1, wszBuf, nBufSize);


// Unicode를 Ascii 로 변환할 경우
WCHAR wszSource[1024] = _T("Sample Unicode string");
char szDest[1024];
int nBufSize = 1024

WideCharToMultiByte( CP_ACP, 0, wszSource, -1, szDest, nBufSize,
NULL, NULL );


MSDN - ATL and MFC String Conversion Macros
MSDN - MultiByteToWideChar
MSDN - WideCharToMultiByte
Original Post :
http://neodreamer-dev.tistory.com/119

VisualSVN Server에 MySQL 과 PHP 붙이기

개발 서버로 VisualSVN Server 를 설치하고 그 위에 MySQL과 PHP를 얹어 보았다.

나중에 Bug Tacker 를 올리기 위한 초석이다.

MySQL과 PHP를 연동하는 문제는 그리 어렵지 않다.

우선 mysql 무설치 본PHP를 받아 특정 디토리에 설치를 한다.

mysql 은 C:\Mysql 에 설치를 했고 php 는 C:\php 에 설치를 하였다.

mysql 디렉토리에 있는 my-large.ini 파일을 c:\ 에 my.ini 파일로 복사를 하고 mysql 의 bin 디렉토리에서 서비스를 등록한다.

    mysqld-nt.exe --install

php 디렉토리에 php.ini 파일에서 mysql 관련 설정을 활성화 한다.
사용자 삽입 이미지

php 폴더의 libmysql.dll 과 php_mysql.dll 을 system32 폴더에 복사한다.

VisualSVN Server 의 설치 경로의 conf 폴더에 httpd-custom.conf 파일에 php를 활성화 하기 위한 코드를 넣어 준다.

# For PHP 5 do something like this:
LoadModule php5_module "c:/php/php5apache2_2.dll"
AddType application/x-httpd-php .php

# configure the path to php.ini
PHPIniDir "C:/php"



그리고 서버를 재시작 하면 된다.
phpinfo() 함수 실행화면

phpinfo() 함수 실행화면


php에 mysql 활성화 화면

php에 mysql 활성화 화면

Original Post : http://neodreamer-dev.tistory.com/118