출처 : http://blog.danggun.net/2040




wcf가 예전에 사용하던 방식과 달라 이것저것 테스트 하다가 간만에 뜬 에러

 

크로스 스레드 작업이 잘못되었습니다.

아....

 

예전에 WPF에서 한번 소개 하긴 했었습니다만 윈폼에서는 약간다르죠.

(참고 : [WPF] 다른 쓰레드에서 UI쓰레드 접근하기 - Dispatcher.Invoke)

 

 

1. 일반적인 방법

일반적으로 인보크(Invoke)를 사용하려면 델리게이트(Delegate)를 만들어야 합니다.

(참고 : MSDN - Control.Invoke 메서드)

 

일반적인 방법에서는 다음과 같은 순서로 인보크를 사용합니다.

1) 델리게이트 선언

2) 델리게이트에 연결할 함수 생성

3) 델리게이트와 생성한 함수 연결

4) 인보크로 델리게이트 호출

 

 

//1) 델리게이트 선언
/// <summary>
/// 델리게이트 선언(연결 할 함수와 같은 모양이 되도록 만든다.)
/// </summary>
/// <param name="sData"></param>
private delegate void DataDelegate(string sData);

//2) 델리게이트에 연결할 함수 생성
/// <summary>
/// 실제 동작하는 함수(연결 할 함수)
/// </summary>
private void DelegteFuntion(string sData)
{
	label2.Text = sData;
}

//3) 델리게이트와 생성한 함수 연결
//4) 인보크로 델리게이트 호출
//사용할때
this.Invoke(new DataDelegate(DelegteFuntion), "Test!");

 

코드 라인끝

 

이 방법의 가장큰 문제는 원하는 동작만큼 델리게이트를 선언해야 한다는 것입니다-_-;;;;;

그래서 간소화 방법을 사용하죠.

 

 

 

 

 

 

2. 간소화 방법

간소화 방법은 일반적인 방법과는 달리 한줄로  델리게이트를 선언하는 방법 입니다.

메소드인보커 대리자(MethodInvoker Delegate)를 이용하는 방법이죠.

(참고 : MSDN - MethodInvoker 대리자)

 

this.Invoke(new Action(
	delegate()
	{
		label2.Text = "Test";
	}));

//혹은

this.Invoke(new MethodInvoker(
	delegate()
	{
		label2.Text = "Test";
	}));

 

 

깔끔하게 됐죠?

 

메소드인보커를 이용하면 델리게이트를 전역으로 선언하지 않고 사용할수 있습니다.

단 해당 데리자를 따로 저장하지 않으면 1회만 사용할 수 있습니다.

 

 

3. 자신의 쓰래드인지 확인하기

하지만 자신의 쓰래드에서 인보크를 시도하면 에러가 납니다.

이걸 해결하려면 'InvokeRequired'속성을 써야 합니다.

'InvokeRequired'속성은 'System.Windows.Forms'에 속해있는 속성으로 호출된 메소드가 같은 쓰래드인지 아닌지 확인해 줍니다.

if( true == InvokeRequired)
{
	//다른 쓰래드다.
}
else
{
	//같은 쓰래드다.
}

다른 쓰래드일때는 인보크를 해야하고 같은 쓰래드일때는 필요없습니다.

마무리

검색하다가 안 사실이지만 의외로 델리게이트를 간략화 해서 쓰는걸 모르시는 분들이 많으시군요 ㅡ.ㅡ;;;

제 기억으론 책에서도 나왔던거 같은데;;;(아닌가?)

이럴줄 알았으면 빨리 포스팅을 하는 거였는데 ㅡ,.ㅡ;;;

 

 

 


'language > C#' 카테고리의 다른 글

[.Net] 크로스 스레드(Cross Thread) 오류 해결을 위한 인보크(Invoke)  (0) 2017.09.29
전역 후킹  (0) 2014.08.29
Diskflt.sys 치료 코드  (0) 2014.08.27
디어셈블러  (0) 2013.08.23
[C#] VisualStudio 디버깅 중 Memory 영역을 보는 방법  (0) 2013.07.04
C# DataGridView  (0) 2013.06.05

전역 후킹

language/C# 2014.08.29 15:20 posted by muhan56

http://www.codeproject.com/Articles/5038/Using-Hooks-from-C


http://support.microsoft.com/default.aspx?scid=kb;en-us;318804


http://www.codeproject.com/Articles/7294/Processing-Global-Mouse-and-Keyboard-Hooks-in-C

'language > C#' 카테고리의 다른 글

[.Net] 크로스 스레드(Cross Thread) 오류 해결을 위한 인보크(Invoke)  (0) 2017.09.29
전역 후킹  (0) 2014.08.29
Diskflt.sys 치료 코드  (0) 2014.08.27
디어셈블러  (0) 2013.08.23
[C#] VisualStudio 디버깅 중 Memory 영역을 보는 방법  (0) 2013.07.04
C# DataGridView  (0) 2013.06.05

Diskflt.sys 치료 코드

language/C# 2014.08.27 10:33 posted by muhan56


  



using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; using System.IO; using Microsoft.Win32; using Microsoft.Win32.SafeHandles; namespace diskflt_unload { class Program { #region [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool CloseHandle(IntPtr hObject); //CheckDiskFltInfected [DllImport("advapi32.dll", EntryPoint = "OpenSCManagerW", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)] internal static extern IntPtr OpenSCManager( string machineName, string databaseName, uint dwAccess); [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)] static extern IntPtr OpenService(IntPtr hSCManager, string lpServiceName, uint dwDesiredAccess); [DllImport("advapi32.dll")] private static extern int QueryServiceStatus(IntPtr hService, ref SERVICE_STATUS lpServiceStatus); [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool CloseServiceHandle(IntPtr hSCObject); [StructLayout(LayoutKind.Sequential)] public struct SERVICE_STATUS { public int dwServiceType; public int dwCurrentState; public int dwControlsAccepted; public int dwWin32ExitCode; public int dwServiceSpecificExitCode; public int dwCheckPoint; public int dwWaitHint; } //SysFileLoad [DllImport("kernel32.dll")] static extern bool FlushViewOfFile(IntPtr lpBaseAddress, uint dwNumberOfBytesToFlush); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] public static extern IntPtr GetModuleHandle(string lpModuleName); [DllImport("kernel32.dll", SetLastError = true)] [PreserveSig] public static extern uint GetModuleFileName ( [In] IntPtr hModule, [Out] StringBuilder lpFilename, [In][MarshalAs(UnmanagedType.U4)] int nSize ); [DllImport("advapi32.dll", EntryPoint = "RegCreateKeyA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)] private static extern int RegCreateKey(int hKey, [MarshalAs(UnmanagedType.VBByRefStr)] ref string lpSubKey, ref int phkResult); [DllImport("advapi32.dll", SetLastError = true)] static extern int RegSetValueEx( IntPtr hKey, [MarshalAs(UnmanagedType.LPStr)] string lpValueName, int Reserved, Microsoft.Win32.RegistryValueKind dwType, [MarshalAs(UnmanagedType.LPStr)] string lpData, int cbData); [DllImport("advapi32.dll", SetLastError = true)] private static extern int StartService(IntPtr hService, int dwNumServiceArgs, int lpServiceArgVectors); [DllImport("kernel32.dll", SetLastError = true)] static extern bool UnmapViewOfFile(IntPtr lpBaseAddress); [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)] private static extern IntPtr CreateService( IntPtr hSCManager, string lpServiceName, string lpDisplayName, ServiceAccessRights dwDesiredAccess, int dwServiceType, ServiceBootFlag dwStartType, ServiceError dwErrorControl, string lpBinaryPathName, string lpLoadOrderGroup, IntPtr lpdwTagId, string lpDependencies, string lp, string lpPassword); [Flags] public enum ServiceAccessRights { QueryConfig = 0x1, ChangeConfig = 0x2, QueryStatus = 0x4, EnumerateDependants = 0x8, Start = 0x10, Stop = 0x20, PauseContinue = 0x40, Interrogate = 0x80, UserDefinedControl = 0x100, Delete = 0x00010000, StandardRightsRequired = 0xF0000, AllAccess = (StandardRightsRequired | QueryConfig | ChangeConfig | QueryStatus | EnumerateDependants | Start | Stop | PauseContinue | Interrogate | UserDefinedControl) } public enum ServiceBootFlag { Start = 0x00000000, SystemStart = 0x00000001, AutoStart = 0x00000002, DemandStart = 0x00000003, Disabled = 0x00000004 } public enum ServiceError { Ignore = 0x00000000, Normal = 0x00000001, Severe = 0x00000002, Critical = 0x00000003 } [DllImport("kernel32.dll", CharSet = CharSet.Auto)] public static extern int GetLastError(); //DiskFltPatch [DllImport("kernel32", SetLastError = true)] internal static extern IntPtr CreateFile( string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile); [DllImport("kernel32.dll", SetLastError = false, CharSet = CharSet.Auto)] static extern bool DeviceIoControl( IntPtr driveHandle, uint ctrlCode, IntPtr inBuffer, int inBufferSize, IntPtr outBuffer, int outBufferSize, ref uint bytesReturned, IntPtr overlapped); //uint bytesReturned; [DllImport("kernel32.dll", SetLastError = true)] static extern IntPtr CreateFileMapping(IntPtr hFile, IntPtr lpFileMappingAttributes, uint flProtect, uint dwMaximumSizeHigh, uint dwMaximumSizeLow, string lpName); [DllImport("kernel32.dll", SetLastError = true)] static extern IntPtr MapViewOfFile(IntPtr hFileMappingObject, uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, uint dwNumberOfBytesToMap); [DllImport("kernel32.dll")] static extern uint GetFileSize(IntPtr hFile, IntPtr lpFileSizeHigh); #endregion static void Main(string[] args) { //감염체크 포함 /* if (CheckDiskFltInfected() == true) { Console.WriteLine("[find DiskFlt!]"); if (SysFileLoad() == true) { Console.WriteLine("[sysload ok]"); if (DiskFltPatch() == true) { //DeleteDiskFltUnInstallSys(); Console.WriteLine("[DiskFlt Patch Success!]"); Console.WriteLine("Reboot은 셀프 'ㅅ')v"); Console.ReadLine(); return; } } } //DeleteDiskFltUnInstallSys(); Console.WriteLine("프로그램 종료"); Console.ReadLine(); */ //감염체크 미포함 if (SysFileLoad() == true) { Console.WriteLine("[sysload ok]"); if (DiskFltPatch() == true) { DeleteDiskFltUnInstallSys(); Console.WriteLine("[DiskFlt Patch Success!]"); Console.WriteLine("Reboot은 셀프"); Console.ReadLine(); return; } } DeleteDiskFltUnInstallSys(); Console.WriteLine("프로그램 종료"); Console.ReadLine(); } static bool CheckDiskFltInfected() { SERVICE_STATUS _ServiceStatus = new SERVICE_STATUS(); IntPtr hOpenSCM = OpenSCManager(null, null, 0x80000000); if ((int)hOpenSCM > 0) { IntPtr hService = OpenService(hOpenSCM, "diskflt", 0x80000000); if ((int)hService > 0) { if (QueryServiceStatus(hService, ref _ServiceStatus) == 1 && _ServiceStatus.dwCurrentState == 4) { CloseServiceHandle(hService); CloseServiceHandle(hOpenSCM); return true; } CloseServiceHandle(hService); } CloseServiceHandle(hOpenSCM); } return false; } static bool SysFileLoad() { //현재 경로 가져오기 StringBuilder builder = new StringBuilder(260); IntPtr hModule = GetModuleHandle("dll.dll"); GetModuleFileName(hModule, builder, 260); CloseHandle(hModule); //리턴된 현재 경로를 string 형변환 string NowPath = builder.ToString(); // 해당 파일의 확장자를 변환 FileInfo ExeFile = new FileInfo(NowPath); //exe 를 sys로 변경 NowPath = NowPath.Replace(ExeFile.Extension, ".sys"); //만약 실행된 프로그램과 동일한 경로에 SYS 파일이 존재하는 경우 FileInfo SysFile = new FileInfo(NowPath); //SYS 파일 유무체크 if (SysFile.Exists == true) { //OpenSCManager IntPtr hOpenSCM = OpenSCManager(null, null, 0x0002); if ((int)hOpenSCM > 1) { //SYS 파일 로드를 위하여 서비스 생성 IntPtr hCreateService = CreateService( hOpenSCM, "DiskFltUninstall", "DiskFltUninstall", ServiceAccessRights.AllAccess, 0x00000001, //SERVICE_KERNEL_DRIVER ServiceBootFlag.DemandStart, ServiceError.Normal, NowPath, null, IntPtr.Zero, null, null, null); if ((int)hCreateService > 0) { //핸들 닫기 CloseServiceHandle(hCreateService); //서비스 찾기 (DiskFltDrvPatch) IntPtr hService = OpenService(hOpenSCM, "DiskFltUninstall", 0xF01FF); if ((int)hService > 1) { // 서비스 동작 StartService(hService, 0, 0); CloseServiceHandle(hService); CloseServiceHandle(hOpenSCM); return true; } CloseServiceHandle(hService); CloseServiceHandle(hOpenSCM); } CloseServiceHandle(hOpenSCM); } } return false; } static unsafe bool DiskFltPatch() { IntPtr v0 = CreateFile("\\\\.\\DiskFlt", 0xc0000000, 0, IntPtr.Zero, 0x03, 0x80, IntPtr.Zero); if ((int)v0 > 0) { //핸들닫기 CloseHandle(v0); //시스템 폴더 경로 가져오기 string DiskFltPath = Environment.SystemDirectory + "\\drivers\\diskflt.sys"; //string DiskFltPath = @"C:\Windows\SysWOW64\drivers\diskflt.sys"; Console.WriteLine("DiskFltPath : {0}", DiskFltPath); //diskflt.sys 접근 IntPtr hDiskFlt = CreateFile(DiskFltPath, 0xc0000000, 0, IntPtr.Zero, 0x03, 0x80, IntPtr.Zero); //diskflt.sys 파일 사이즈 uint DiskFltSize = GetFileSize(hDiskFlt, IntPtr.Zero); if ((int)DiskFltSize > 0) { //diskflt.sys 의 CreateFileMApping IntPtr hDiskFltCFM = CreateFileMapping(hDiskFlt, IntPtr.Zero, 0x04, 0, 0, null); if ((int)hDiskFltCFM > 0) { CloseHandle(hDiskFlt); ////diskflt.sys 의 MapViewOfFile IntPtr hDiskFltMVOF = MapViewOfFile(hDiskFltCFM, 0x02, 0, 0, 0); if ((int)hDiskFltMVOF > 0) { CloseHandle(hDiskFltCFM); //dbggerdbgger변수의 16 진수들은 [dbgger][dbgger]를 뜻한다. byte[] dbggerdbgger = new byte[] { 0x5B, 0x64, 0x62, 0x67, 0x67, 0x65, 0x72, 0x5D, 0x5B, 0x64, 0x62, 0x67, 0x67, 0x65, 0x72, 0x5D }; //Diskflt 중간부분에 패치할 바이너리 byte[] BinaryPatchCode = new byte[] { 0x8c, 0xf8, 0xc8, 0x9d, 0x06, 0xe9, 0xdd, 0x30, 0x42, 0x6d, 0x01, 0xc7, 0x32, 0xcf, 0x3f, 0xf5 }; //DiskFlt 주소 값 byte* DiskFltBinary = (byte*)hDiskFltMVOF.ToPointer(); //[dbgger][dbgger] 찾기 for (int a = 0; a <= (int)DiskFltSize; a++) { //검색 시간을 줄이기 위한 필터 if (*(DiskFltBinary + a) == dbggerdbgger[0] && *(DiskFltBinary + a + 8) == dbggerdbgger[8]) { //[dbgger][dbgger] 문자열이 순서대로 존재하는지 체크 for (int b = 0; b != dbggerdbgger.Length; b++) { if (*(DiskFltBinary + a + b) == dbggerdbgger[b] && dbggerdbgger.Length - 1 == b) { //바이너리 패치 *(DiskFltBinary + a + 34) = 0x00; *(DiskFltBinary + a + 58 + 0) = BinaryPatchCode[0]; *(DiskFltBinary + a + 58 + 1) = BinaryPatchCode[1]; *(DiskFltBinary + a + 58 + 2) = BinaryPatchCode[2]; *(DiskFltBinary + a + 58 + 3) = BinaryPatchCode[3]; *(DiskFltBinary + a + 58 + 4) = BinaryPatchCode[4]; *(DiskFltBinary + a + 58 + 5) = BinaryPatchCode[5]; *(DiskFltBinary + a + 58 + 6) = BinaryPatchCode[6]; *(DiskFltBinary + a + 58 + 7) = BinaryPatchCode[7]; *(DiskFltBinary + a + 58 + 8) = BinaryPatchCode[8]; *(DiskFltBinary + a + 58 + 9) = BinaryPatchCode[9]; *(DiskFltBinary + a + 58 + 10) = BinaryPatchCode[10]; *(DiskFltBinary + a + 58 + 11) = BinaryPatchCode[11]; *(DiskFltBinary + a + 58 + 12) = BinaryPatchCode[12]; *(DiskFltBinary + a + 58 + 13) = BinaryPatchCode[13]; *(DiskFltBinary + a + 58 + 14) = BinaryPatchCode[14]; *(DiskFltBinary + a + 58 + 15) = BinaryPatchCode[15]; break; } } } } //SYS 파일 CheckSum 변경. int PEaddr = (*(DiskFltBinary + 0x3F) * 0x1000000) + (*(DiskFltBinary + 0x3E) * 0x10000) + (*(DiskFltBinary + 0x3D) * 0x100) + (*(DiskFltBinary + 0x3C)); *(DiskFltBinary + PEaddr + 0x58) = 0xDD; *(DiskFltBinary + PEaddr + 0x59) = 0x57; *(DiskFltBinary + PEaddr + 0x5A) = 0x02; *(DiskFltBinary + PEaddr + 0x5B) = 0x00; //Diskflt 파일 FlushViewOfFile IntPtr v3 = CreateFile("\\\\.\\DiskFlt", 0xC0000000, 0, IntPtr.Zero, 0x03, 0x80u, IntPtr.Zero); uint bytesReturned = 0; if ((int)v3 > 0) { IntPtr sptr = Marshal.StringToHGlobalAnsi("wowocock"); bool v5 = DeviceIoControl(v3, 0x80002000, sptr, 0x08, IntPtr.Zero, 0, ref bytesReturned, IntPtr.Zero); if (v5 == true) { FlushViewOfFile(hDiskFltMVOF, 0); DeviceIoControl(v3, 0x80002004, IntPtr.Zero, 0, IntPtr.Zero, 0, ref bytesReturned, IntPtr.Zero); UnmapViewOfFile(hDiskFltMVOF); CloseHandle(v3); CloseHandle(sptr); CloseHandle(hDiskFltMVOF); return true; } CloseHandle(v3); CloseHandle(sptr); CloseHandle(hDiskFltMVOF); } } CloseHandle(hDiskFltCFM); } } } return false; } //pass static void DeleteDiskFltUnInstallSys() { RegistryKey Rk = Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Services\\DiskFltUninstall"); if (Rk != null) { Registry.LocalMachine.DeleteSubKey(@"SYSTEM\\CurrentControlSet\\Services\\DiskFltUninstall\\Enum"); Registry.LocalMachine.DeleteSubKey(@"SYSTEM\\CurrentControlSet\\Services\\DiskFltUninstall\\Security"); Registry.LocalMachine.DeleteSubKey(@"SYSTEM\\CurrentControlSet\\Services\\DiskFltUninstall"); } } //pass static bool DeleteDiskFltReg() { //diskflt.sys 경로 가져오기. string DiskFltPath = Environment.SystemDirectory + "\\drivers\\diskflt.sys"; FileInfo fDiskFlt = new FileInfo(DiskFltPath); //파일삭제 fDiskFlt.Delete(); RegistryKey regDiskFltService = Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Services", true); if (regDiskFltService != null) { regDiskFltService.DeleteSubKey("diskflt"); regDiskFltService.Close(); RegistryKey regDiskFltUpperFilter = Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E967-E325-11CE-BFC1-08002BE10318}", true); if (regDiskFltUpperFilter != null) { string UpperFiltersList = (string)regDiskFltUpperFilter.GetValue("UpperFilters"); if (UpperFiltersList != null) { UpperFiltersList.Replace("diskflt", ""); return true; } } regDiskFltUpperFilter.Close(); } regDiskFltService.Close(); return false; } } }



'language > C#' 카테고리의 다른 글

[.Net] 크로스 스레드(Cross Thread) 오류 해결을 위한 인보크(Invoke)  (0) 2017.09.29
전역 후킹  (0) 2014.08.29
Diskflt.sys 치료 코드  (0) 2014.08.27
디어셈블러  (0) 2013.08.23
[C#] VisualStudio 디버깅 중 Memory 영역을 보는 방법  (0) 2013.07.04
C# DataGridView  (0) 2013.06.05

디어셈블러

language/C# 2013.08.23 11:06 posted by muhan56




아직은 미완성이지만, 언젠간 완성시키겠다! ㅋㅋㅋ

'language > C#' 카테고리의 다른 글

전역 후킹  (0) 2014.08.29
Diskflt.sys 치료 코드  (0) 2014.08.27
디어셈블러  (0) 2013.08.23
[C#] VisualStudio 디버깅 중 Memory 영역을 보는 방법  (0) 2013.07.04
C# DataGridView  (0) 2013.06.05
C#에서 win32 api를 사용할 때  (0) 2013.04.18



Alt + Ctrl + M + 1 ~ 5


변수를드래그 후 메모리 창에 던져주면 된다.


'language > C#' 카테고리의 다른 글

Diskflt.sys 치료 코드  (0) 2014.08.27
디어셈블러  (0) 2013.08.23
[C#] VisualStudio 디버깅 중 Memory 영역을 보는 방법  (0) 2013.07.04
C# DataGridView  (0) 2013.06.05
C#에서 win32 api를 사용할 때  (0) 2013.04.18
PE 파일 CheckSum 공식  (0) 2013.04.17

C# DataGridView

language/C# 2013.06.05 14:05 posted by muhan56

using System;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;

namespace MyWinForm
{
    public partial class FormDGV1 : Form
    {
        public FormDGV1()
        {
            InitializeComponent();
        }

        private void FormDGV1_Load(object sender, EventArgs e)
        {
            // DataSet을 가져온다
            DataSet ds = GetData();

            // DataSource 속성을 설정
            dataGridView1.DataSource = ds.Tables[0];
        }

        private DataSet GetData()
        {
            string strConn = "Data Source=.;Initial Catalog=TestDB;Integrated Security=SSPI;";
            SqlConnection conn = new SqlConnection(strConn);            
            SqlDataAdapter adapter = new SqlDataAdapter("SELECT * FROM Scores", conn);            
            DataSet ds = new DataSet();
            adapter.Fill(ds);
            return ds;
        }
    }
}

'language > C#' 카테고리의 다른 글

디어셈블러  (0) 2013.08.23
[C#] VisualStudio 디버깅 중 Memory 영역을 보는 방법  (0) 2013.07.04
C# DataGridView  (0) 2013.06.05
C#에서 win32 api를 사용할 때  (0) 2013.04.18
PE 파일 CheckSum 공식  (0) 2013.04.17
Environment  (0) 2013.02.26

출처: http://www.winapi.co.kr




원형 :

int GetSystemMetrics( int nIndex );



인자값을 

SM_CXSCREEN -> 데스크탑의 가로 길이

SM_CYSCREEN -> 데스크탑의 세로 길이


를 반환한다.



Ex)


int width = GetSystemMetrics(SM_CXSCREEN);



int height = GetSystemMetrics(SM_CYSCREEN);



이 외에도 



SM_CLEANBOOT : 시스템이 어떻게 부팅되었는지를 조사한다. 0이면 보통 모드로 부팅된 것이고 1이면 세이프 모드로 부팅한 것이고 2이면 네트웍 지원이 있는 세이프 모드


SM_CMONITORS : 데스크탑의 모니터 개수


SM_CMOUSEBUTTONS : 마우스의 버튼 개수. 0이면 마우스가 설치되어 있지 않다


SM_CXBORDER, SM_CYBORDER : 윈도우 경계선의 폭과 높이를 픽셀 단위로 조사한다. 3D 스타일의 SM_CXEDGE와 동일하다.


SM_CXDRAG, SM_CYDRAG : 최초 마우스 버튼을 누른 후 드래그를 시작하기 위해 움직여야 하는 거리를 조사한다.


SM_CXHSCROLL, SM_CYHSCROLL : 스크롤 바의 화살표 비트맵의 폭과 높이.


SM_CXICON, SM_CYICON : 아이콘의 폭과 높이. LoadIcon은 이 크기의 아이콘만 읽을 수 있다.





등등 윈도우의 특정부분 크기를 재거나,하드웨어적 정보를 얻을 수 있다.










해상도 관련 함수로만 알고 있었는데, 어떤 모드로 부팅했는지 알 수 있다고 함...헐헐 




C#에서 win32 api를 사용할 때

language/C# 2013.04.18 11:14 posted by muhan56

http://www.codegod.com/Win32APIViewer.aspx


참고.

'language > C#' 카테고리의 다른 글

[C#] VisualStudio 디버깅 중 Memory 영역을 보는 방법  (0) 2013.07.04
C# DataGridView  (0) 2013.06.05
C#에서 win32 api를 사용할 때  (0) 2013.04.18
PE 파일 CheckSum 공식  (0) 2013.04.17
Environment  (0) 2013.02.26
C#에서 인라인 어셈을 사용할 수 있을까?  (0) 2012.06.11

유저/커널 메로리의 특징

language/Information 2013.04.17 17:54 posted by muhan56

 위의 그림에 나와있는 pagefile.sys가 바로 그 역할을 하는 파일입니다.(이 파일을 보기 위해서는 도구->폴

더 옵션->보기에서 보호된 운영 체제 파일 숨기기의 체크를 없애주셔야 합니다.) 윈도우는 해당 사이즈만큼을 

가상 메모리로 사용하면서 당장 사용하지 않는 프로그램 코드 값이나 자료들을 pagefile.sys에 저장하고 필요

할 때 메모리로 읽어오게 됩니다.(기타 가상 메모리에 대한 개념이나 관련 메커니즘은 운영체제 개론서를 보

시면 잘 나와 있습니다.) 

 어쨌든 윈도우는 이러한 가상 메모리 기법을 사용해서 최대 4GBytes(2^32bytes)의 메모리를 관리할 수 있

습니다. 그리고 이 전체 메모리를 반으로 나눠서 각각 커널 모드와 유저 모드에서 사용하도록 구분을 지어 놓

고 있습니다. 

하위 2Gbytes가 유저 모드를 위한 메모리이며 상위 2Gbytes가 커널을 위한 메모리입니다. 유저모드 프로그

램에서 디바이스 드라이버와 같은 커널 모드 프로그램에 데이터를 전달하기 위해서는 - 혹은 전달 받기 위해

서는 – 특별한 방식이 필요합니다. 그 이유는 두 모드에서 메모리를 관리하는 방식에 있어 차이가 있기 때문

입니다. 

유저 모드는 메모리 관리에 있어서 다음과 같은 특성이 있습니다. 


1. 모든 할당되는 메모리는 페이지라고 하는 일정 크기의 블록으로 관리됩니다. 그 이유는 앞에서 언급한 가상 메모리 방식 때문입니다. 윈도우는 가상 메모리 방식에 의해 현재 사용되는 않는 메모리는 

하드 디스크에 옮겨 놓고 필요한 메모리를 가져오게 되는데 이 때 보다 높은 효율성과 관리의 편의성

을 위해 일정 사이즈로 블록화 시켜 관리하게 됩니다. 그리고 이러한 메모리를 페이지 메모리(Paged 

Memory)라고 합니다. 


2. 프로세스 별로 메모리가 관리됩니다. 따라서 현재 사용되지 않는 프로세스(Idle Process)에 할당된 메

모리는 하드 디스크로 옮겨지고 현재 메모리에서 삭제 됩니다. 이것을 Swap Out이라고 합니다. 반대

로 다시 해당 프로세스가 사용되게 되면 다시 메모리로 옮겨오게 되는데 이것을 Swap In이라고 하고 

이렇게 Swap Out과 In을 하는 동작을 Swapping이라고 합니다. 


3. 유저 모드 프로세스는 커널 모드 메모리를 참조하거나 변경하지 못합니다. 이것은 윈도우의 메모리 

보호 정책에 의해서 보장되며 이러한 특성 때문에 유저 모드 프로그램에서 발생된 어떠한 에러도 시

스템에 문제를 일으키지 못합니다.(우리가 어떤 프로그램을 사용하다가 에러에 의해 프로그램이 다운

되더라도 해당 프로그램을 종료하면 다시 원상태로 복구될 수 있는 것은 이러한 이유 때문입니다) 만

약 커널 모드 메모리를 참조/쓰기 하려고 하게 되면 Access Violation 에러를 일으키며 윈도우는 해

당 프로세스를 강제로 종료시키게 됩니다. 


4. 3의 특성에서 하나 더 나아가 다른 프로세스들 간에도 메모리를 함부로 참조/변경하지 못하도록 윈도

우에서 보호해 줍니다.(CreateFileMapping()과 같은 API를 사용하면 이러한 제약을 부분적으로 없애

줘서 프로세스간에 메모리 공유가 가능합니다.) 


반면 커널 메모리는 다음과 같은 특성이 있습니다. 


1. 할당되는 메모리는 페이지 될 수도 있고 그렇지 않을 수도 있습니다. 페이지 메모리는 스와핑이 일어

나기 때문에 해당 데이터가 반드시 현재 메모리에 있다는 보장이 없습니다. 이것은 일반 유저 모드 

프로그램에서는 큰 문제가 되지 않지만(스와핑에 의해 필요할 때마다 다시 불려질 수 있으므로) 윈도

우 커널의 핵심 코드나 데이터의 경우 큰 문제가 될 수 있습니다. (예를 들어 스와핑 작업을 담당하는 

커널 명령 루틴자체가 메모리에서 페이지 아웃되어 있다고 생각해 보시기 바랍니다…) 따라서 커널 

모드 프로세스에서는 중요한 루틴이나 데이터들은 항상 메모리에 있도록 보장할 수 있어야 합니다. 

그리고 그렇게 하기 위해서는 중요한 데이터나 실행 코드들은 페이지 되지 않은 메모리에 저장해서 

스와핑을 막게 됩니다. (사실 여기서 설명한 내용은 정확하다고 볼 수 없습니다. 커널 모드에서 스와

핑이 일어나서는 안 되는 보다 정확한 이유는 뒤에서 설명하도록 하겠습니다.) 


2. 유저 모드 프로그램과 달리 커널 모드 프로세스들은 다른 프로세스들간에 메모리 보호가 되지 못합니

다. 따라서 메모리 관리를 잘못하게 되면 다른 중요한 시스템 데이터가 손상될 수도 있습니다.(커널 

모드에서는 윈도우가 제공하는 메모리 보호 정책이 적용되지 않습니다.) 


3. 커널 모드 프로세스들은 유저 모드 메모리를 직접 참조할 수 있습니다. 하지만 여러 가지 위험이 발

생하는데 이것에 대해서는 바로 밑에서 설명하겠습니다.




이러한 특성들 때문에 커널 모드에서 동작하는 디바이스 드라이버와 유저 모드 프로그램간에는 데이터를 주고 

받음에 있어서 여러 가지 제약이 발생하게 됩니다. 

 예를 들어 유저 모드 프로그램에서 드라이버에게 어떤 데이터를 주고자 한다면 커널 모드 메모리에 직접 데

이터를 쓰지 못하므로 문제가 생깁니다. 반대로 드라이버에서 데이터를 가져오는 것도 불가능 합니다. 

 반대로 드라이버에서 유저 모드 프로그램에게 데이터를 넘겨주거나 읽어온다고 할 때도 문제가 생깁니다. 왜

냐하면 위에 유저 메모리 특성에서 설명했듯이 유저 모드 프로세스의 메모리는 스와핑이 일어나기 때문입니다. 

자세하게 설명하자면, 윈도우는 아시다시피 멀티 프로세싱(예를 들어 현재 인터넷 검색을 하면서 워드 작업)

이 가능합니다. 이것은 윈도우에서 사용자가 하나의 프로그램을 사용하는 동안에도 틈틈이 다른 프로세스의 

작업을 수행하기 때문입니다. 다시 말하면 여러 개의 프로세스가 돌아가면서 동작한다는 것을 뜻하며 현재 우

리 드라이버가 데이터를 참조하고자 하는 프로그램의 메모리가 스와핑 될 가능성을 항상 가지고 있다는 것을 

의미하기도 합니다. 

 그러므로 만약 드라이버에서 유저 모드 프로그램의 메모리를 직접 참조하려고 하면 – 물론 운이 좋아 안 일

어날 수도 있지만 – 스와핑이 이미 일어나서 드라이버가 참조하고자 하는 물리 메모리 영역에는 엉뚱한 값들

이 들어있을 수가 있습니다. 

 때문에 윈도우(정확하게 말하자면 I/O manager)에서는 커널 모드와 유저 모드간에 데이터를 주고 받기 위해

크게 두 가지 방식을 제공합니다. 




1. Buffered I/O 

A. 만약 유저 모드 프로그램과 드라이버간에 데이터를 주고 받는 요청이 발생하면 I/O manager에서

는 해당 데이터의 사이즈를 먼저 체크한 후 해당 데이터가 들어갈 만한 충분한 사이즈의 페이지 

되지 않은 버퍼메모리를 생성합니다. 


B. 필요하다면(드라이버에 데이터를 쓰는 작업의 경우) 유저 모드 데이터를 이 버퍼에 복사합니다. 


C. 드라이버에서 이 버퍼 메모리의 값을 참조하거나 혹은 – 데이터 읽기 작업일 경우 – 버퍼에 드

라이버가 가지고 있는 데이터를 저장합니다. 


D. 해당 작업이 완료되면 I/O manager는 버퍼에 있는 데이터를 다시 유저 모드 메모리에 복사하고 

버퍼메모리를 해제합니다. 



2. Direct I/O 

A. 데이터를 주고 받는 요청이 발생하면 I/O manager에서 해당 메모리가 스와핑이 되지 않도록 일

종의 잠금 장치를 합니다. 


B. 잠겨진(Locked) 메모리를 드라이버에서 쉽게 참조할 수 있도록 관련 정보가 저장된 Memory 

Desctriptor List(MDL)라는 것을 만듭니다. 


C. 드라이버에서는 MDL을 가지고 참조 가능한 메모리 포인터를 리턴 해주는 MmGetSystemAddresForMdl()이라고 하는 API를 사용하여 데이터를 주고 받을 포인터를 만들고 이 포인터를 

이용해서 데이터 처리를 합니다. 


D. I/O manager는 쓰기/읽기 동작이 완료되면 MDL을 제거하고 해당 메모리의 잠금 장치를 해제합

니다. 

'language > Information' 카테고리의 다른 글

유저/커널 메로리의 특징  (0) 2013.04.17
메일슬롯(MailSlot) IPC 통신 소스  (0) 2013.04.11
Window os 버전 구하기  (0) 2013.01.14
드라이버 공부에 도움되는 링크!  (0) 2012.10.04
OS 버전 구하기  (0) 2012.04.18
윈도우 이벤트  (0) 2011.11.17

드라이버 MajorFunction

language/Driver 2013.04.17 16:06 posted by muhan56

 ☞ DeviceObject - 드라이버가 가장 최근에 생성한 DeviceObject를 가르키는 포인터 
 ☞ DeviceExtension - 하위 레벨 드라이버에서 하드웨어 장치와 주변 장치들을 관리하기위한 PnP 지원 필드
 ☞ DriverStart - 드라이버가 메모리에 보관된 시작 위치
 ☞ DriverName - 드라이버의 서비스 이름
 ☞ HardwareDatabase - 드라이버가 등록되어 있는 서비스 키
 ☞ DriverInit - DriverEntry 함수 주소
 ☞ MajorFunction - 드라이버가 처리하는 IRP 명령어를 위한 Dispatch Routine들



출처 : http://hasu0707.tistory.com/211