Автор работы: Пользователь скрыл имя, 19 Марта 2012 в 10:58, курсовая работа
Данная курсовая работа посвящена рассмотрению принципов работы API-функций операционной системы Windows.
Win API - это набор функций, предоставляемых операционной системой каждой программе. Эти функции находятся в стандартных динамически компонуемых библиотеках (Dynamic Linked Library, DLL), таких как kernel32.dll, user32.dll, gdi32.dll. Эти файлы находятся в директории Window\System.
I. Теоретическая часть
Глава 5. Синхронизация
5.1. Непрерывные действия и команды
5.2. Определение синхронизации
5.3. Программная реализация синхронизации
5.4. Аппаратная реализация синхронизации
5.5. Примитивы синхронизации
Глава 6. Синхронизация потоков в Windows
6.1. Критические секции
6.2. Объекты синхронизации и функции ожидания
6.3. Мьютексы
6.4. События
6.5. Семафоры
Глава 44. Работа со списками управления доступом на низком уровне
44.1. Структура списка управления доступом
44.2. Структура элемента списка управления доступом
44.3. Инициализация списка управления доступом
44.4. Проверка достоверности списка управления доступом
44.5. Добавление элементов в список управления доступом
44.6. Получение элементов из списка управления доступом
44.7. Удаление элементов из списка управления доступом
44.8. Получение информации о списке управления доступом
44.9. Установка версии списка управления доступом
44.10. Определение доступной памяти
II. Практическая часть
Глава 6. Синхронизация потоков в Windows
6.1. Критические секции
6.2. Объекты синхронизации и функции ожидания
6.3. Мьютексы
6.4. События
6.5. Семафоры
Глава 44. Работа со списками управления доступом на низком уровне
44.1. Структура списка управления доступом
44.2. Структура элемента списка управления доступом
44.3. Инициализация списка управления доступом
44.4. Проверка достоверности списка управления доступом
44.5. Добавление элементов в список управления доступом
44.6. Получение элементов из списка управления доступом
44.7. Удаление элементов из списка управления доступом
44.8. Получение информации о списке управления доступом
44.9. Установка версии списка управления доступом
44.10. Определение доступной памяти
Приложение.
Заключение
Список использованной литературы
WS_BORDER | WS_CHILD |
WS_VISIBLE | WS_CLIPCHILDREN,
0, 0, 0, 0, hwndParent, NULL,
hInst, NULL );
if( ! hwndChild[iCount] ) return( FALSE );
}
return( TRUE );
}
LRESULT WINAPI Main_WndProc( HWND hWnd, // message address
UINT uMessage, // message type
WPARAM wParam, // message contents
LPARAM lParam ) // more contents
{
int wmId, wmEvent;
switch( uMessage )
{
case WM_CREATE:
{
Main_OnCreate(hWnd, NULL);
// HANDLE_MSG( hWnd, WM_CREATE, Main_OnCre
// create the window and the threads break;
case WM_SIZE: {
wmId = LOWORD(lParam);
wmEvent = HIWORD(lParam);
Main_OnSize(hWnd,wParam,wmId,
// HANDLE_MSG( hWnd, WM_SIZE, Main_OnSize );
// reposition the child windows when the main window changes
break;
}
case WM_TIMER:
{
Main_OnTimer(hWnd,TIMER);
// HANDLE_MSG( hWnd, WM_TIMER, Main_OnTimer );
// update the list box every five seconds
break;
}
case WM_INITMENU:
{
Main_OnInitMenu(hWnd,hMenu);
// HANDLE_MSG( hWnd, WM_INITMENU, Main_OnInitMenu );
// put a check by the Use Mutex menu item if bUseMutex is TRUE
break;
}
case WM_COMMAND:
{
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
Main_OnCommand(hWnd,wmId,hWnd,
// HANDLE_MSG( hWnd, WM_COMMAND, Main_OnCommand );
// process menu commands
break;
}
case WM_DESTROY:
{
/*
for( iCount = 0; iCount < 4; iCount++ )
{
TerminateThread(hThread[
}
*/
//PostMessage(hWnd, WM_CLOSE, 0, 0); //опубликовать сообщение о закрытии приложения.
//PostMessage(hWnd,WM_CLOSE,0,
PostQuitMessage( 0 );
// HANDLE_MSG( hWnd, WM_DESTROY, Main_OnDestroy );
// clean up and quit
break;
}
default:
return( DefWindowProc(hWnd, uMessage, wParam, lParam) );
}
return( 0L );
}
BOOL Main_OnCreate( HWND hWnd, LPCREATESTRUCT lpCreateStruct )
{
UINT uRet;
int iCount;
// create the four threads, initially suspended
for( iCount = 0; iCount < 4; iCount++ )
{
iRectCount[iCount] = 0;
dwThreadData[iCount] = iCount;
hThread[iCount] = CreateThread( NULL, 0,
(LPTHREAD_START_ROUTINE) StartThread,
(LPVOID) ( & ( dwThreadData[iCount] ) ),
CREATE_SUSPENDED,
(LPDWORD) ( & ( dwThreadID[iCount] ) ) );
if( ! hThread[iCount] ) // was the thread created?
{
return( FALSE );
}
}
// create a timer with a five-second period
// the timer is used to update the list box
//uRet = SetTimer( hWnd, TIMER, 5000, NULL );
uRet = SetTimer( hWnd, TIMER, 100, NULL );
if( ! uRet )
{ // unable to create the timer
return( FALSE );
}
// create a mutex synchronization object
hDrawMutex = CreateMutex( NULL, FALSE, NULL );
if( ! hDrawMutex )
{ // unable to create mutex
KillTimer( hWnd, TIMER ); // stop the timer
return( FALSE );
}
// start the threads with a priority below normal
for( iCount = 0; iCount < 4; iCount++ )
{
SetThreadPriority( hThread[iCount], THREAD_PRIORITY_BELOW_NORMAL );
iState[iCount] = ACTIVE;
ResumeThread( hThread[iCount] );
}
// Now all four threads are running!
return( TRUE );
}
void Main_OnSize( HWND hWnd, UINT uState, int cxClient, int cyClient )
{
char* szText = "No Thread Data";
int iCount;
// Suspend all active threads while the windows
// resize and repaint themselves. This pause
// enables the screen to update more quickly.
for( iCount = 0; iCount < 4; iCount++ )
{
if( iState[iCount] == ACTIVE )
SuspendThread( hThread[iCount] );
}
// Place the list box across the top 1/4 of the window.
MoveWindow( hwndList, 0, 0, cxClient, cyClient / 4, TRUE );
// Spread the 4 child windows across the bottom 3/4 of the
// window. (The left border of the first one should be 0.)
MoveWindow( hwndChild[0], 0, cyClient / 4 - 1, cxClient / 4 + 1,
cyClient, TRUE );
for( iCount = 1; iCount < 4; iCount++ )
{
MoveWindow( hwndChild[iCount], (iCount * cxClient) / 4,
cyClient / 4 - 1, cxClient / 4 + 1, cyClient, TRUE );
}
// Add the default strings to the list box, and initialize
// the number of figures drawn to zero.
for( iCount = 0; iCount < 4; iCount++ )
{
iRectCount[iCount] = 0;
//ListBox_AddString( hwndList, szText );
SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)(LPCTSTR)szText);
}
//ListBox_SetCurSel(hwndList, 0);
SendMessage(hwndList, LB_SETCURSEL, 0, 0);
// Reactivate the threads that were suspended while redrawing.
for( iCount = 0; iCount < 4; iCount++ )
{
if( iState[iCount] == ACTIVE )
{
ResumeThread( hThread[iCount] );
}
}
return;
}
void Main_OnTimer( HWND hWnd, UINT uTimerID )
{
// update the data shown in the list box
UpdateListBox();
return;
}
/*
The Main_OnInitMenu function is simply used to check (or uncheck) the Use Mutex menu command.
*/
/*————————————————————————————
MAIN_ONINITMENU
Check or uncheck the Use Mutex menu item based on the
value of bUseMutex.
——————————————————————————————
void Main_OnInitMenu( HWND hWnd, HMENU hMenu )
{
CheckMenuItem( hMenu, IDM_USEMUTEX, MF_BYCOMMAND |
(UINT)( bUseMutex ? MF_CHECKED : MF_UNCHECKED ) );
return;
}
void Main_OnCommand( HWND hWnd, int iCmd, HWND hwndCtl, UINT uCode )
{
switch( iCmd )
{
case IDM_ABOUT: // display the About box
//MakeAbout( hWnd );
break;
case IDM_EXIT: // exit this program
DestroyWindow( hWnd );
break;
case IDM_SUSPEND: // modify the priority or state of a thread
case IDM_RESUME:
case IDM_INCREASE:
case IDM_DECREASE:
DoThread( iCmd ); // adjust a thread
break;
case IDM_USEMUTEX: // toggle the use of the mutex
ClearChildWindows( ); // make all thread windows white
bUseMutex = !bUseMutex; // toggle mutex setting
break;
default:
break;
}
return;
}
void DoThread( int iCmd )
{
int iThread;
int iPriority;
// determine which thread to modify
//iThread = ListBox_GetCurSel( hwndList );
iThread = SendMessage(hwndList, LB_GETCURSEL, 0, 0);
switch( iCmd )
{
case IDM_SUSPEND:
// if the thread is not suspended, then suspend it
if( iState[iThread] != SUSPENDED )
{
SuspendThread( hThread[iThread] );
iState[iThread] = SUSPENDED;
}
break;
case IDM_RESUME:
// if the thread is not active, then activate it
if( iState[iThread] != ACTIVE )
{
ResumeThread( hThread[iThread] );
iState[iThread] = ACTIVE;
}
break;
case IDM_INCREASE:
// increase the thread’s priority (unless it is
// already at the highest level)
iPriority = GetThreadPriority( hThread[iThread] );
switch( iPriority )
{
case THREAD_PRIORITY_LOWEST:
SetThreadPriority( hThread[iThread],
THREAD_PRIORITY_BELOW_NORMAL );
break;
case THREAD_PRIORITY_BELOW_NORMAL:
SetThreadPriority( hThread[iThread],
THREAD_PRIORITY_NORMAL );
break;
case THREAD_PRIORITY_NORMAL:
SetThreadPriority( hThread[iThread],
THREAD_PRIORITY_ABOVE_NORMAL );
break;
case THREAD_PRIORITY_ABOVE_NORMAL:
SetThreadPriority( hThread[iThread],
THREAD_PRIORITY_HIGHEST );
break;
default: break;
} break;
case IDM_DECREASE:
// decrease the thread’s priority (unless it is
// already at the lowest level)
iPriority = GetThreadPriority( hThread[iThread] );
switch( iPriority )
{
case THREAD_PRIORITY_BELOW_NORMAL:
SetThreadPriority( hThread[iThread],
THREAD_PRIORITY_LOWEST );
break;
case THREAD_PRIORITY_NORMAL:
SetThreadPriority( hThread[iThread],
THREAD_PRIORITY_BELOW_NORMAL );
break;
case THREAD_PRIORITY_ABOVE_NORMAL:
SetThreadPriority( hThread[iThread],
THREAD_PRIORITY_NORMAL );
break;
case THREAD_PRIORITY_HIGHEST:
SetThreadPriority( hThread[iThread],
THREAD_PRIORITY_ABOVE_NORMAL );
break;
default: break;
} break;
default: break;
}
return;
}
LONG StartThread ( LPVOID lpThreadData )
{
DWORD *pdwThreadID; // pointer to a DWORD for storing thread’s ID
DWORD dwWait; // return value from WaitSingleObject
// retrieve the thread’s ID
pdwThreadID = (DWORD *)lpThreadData;
// draw continuously until bTerminate becomes TRUE
while( ! bTerminate )
{
if (bUseMutex) // are we using the mutex?
{
// draw when this thread gets the mutex
dwWait = WaitForSingleObject( hDrawMutex, INFINITE );
if( dwWait == 0 )
{
DrawProc( *pdwThreadID ); // draw rectangles
ReleaseMutex( hDrawMutex ); // let someone else draw
}
}
else
{
// not using mutex; let the thread draw
DrawProc( *pdwThreadID );
}
}
// this return statement implicitly calls ExitThread
return( 0L );
}
void DrawProc ( DWORD dwID )
{
int iTotal;
BOOL bError;
RECT rcClient;
long cxClient, cyClient;
HDC hDC;
int xStart,xStop,yStart,yStop,
HBRUSH hBrush;
HGDIOBJ hbrOld;
if (bUseMutex)
{
iTotal = 50; // if only one thread draws at a time,
} // let it draw more shapes at once
else
{
iTotal = 1;
}
// reseed the random generator
//srand( iRandSeed++ );
srand( iRectCount[dwID] );
// get the window’s dimensions
bError = GetClientRect( hwndChild[dwID], &rcClient );
if( ! bError ) return;
cxClient = (long)(rcClient.right - rcClient.left);
cyClient = (long)(rcClient.bottom - rcClient.top);
// do not draw if the window does not have any dimensions
if( ( ! cxClient ) || ( ! cyClient ) )
{
return;
}
// get a device context for drawing
hDC = GetDC( hwndChild[dwID] );
if( hDC )
{
// draw the five random figures
for( iCount = 0; iCount < iTotal; iCount++ )
{
iRectCount[dwID]++;
// set the coordinates
xStart = (int)( rand() % cxClient );
xStop = (int)( rand() % cxClient );
yStart = (int)( rand() % cyClient );
yStop = (int)( rand() % cyClient );
// set the color
iRed = rand() & 255;
iGreen = rand() & 255;
iBlue = rand() & 255;
// create the solid brush
hBrush = CreateSolidBrush( // avoid dithered colors
GetNearestColor( hDC, RGB( iRed, iGreen, iBlue ) ) );
//hbrOld = SelectBrush( hDC, hBrush );
hbrOld = SelectObject( hDC, hBrush );
// draw a rectangle
Rectangle( hDC, min( xStart, xStop ), max( xStart, xStop ),
min( yStart, yStop ), max( yStart, yStop ) );
// delete the brush
//DeleteBrush( SelectBrush(hDC, hbrOld) );
DeleteObject( SelectObject(hDC, hbrOld) );
}
// If only one thread is drawing at a time, clear
// the child window before the next thread draws
if( bUseMutex )
{
//SelectBrush( hDC, GetStockBrush(WHITE_BRUSH) );
SelectObject( hDC, GetStockObject(WHITE_BRUSH) );
PatBlt( hDC, (int)rcClient.left, (int)rcClient.top,
(int)rcClient.right, (int)rcClient.bottom,
PATCOPY );
}
// release the HDC
ReleaseDC( hwndChild[dwID], hDC );
}
return;
}
void UpdateListBox(void)
{
char strNew[100]="";
char buffer[20];
int lastSelection;
int c;
lastSelection=SendMessage(
c=SendMessage(hwndList, LB_GETCOUNT, 0,0);
//remove old items
for( iCount = 0; iCount < c; iCount++ )
{
SendMessage(hwndList, LB_DELETESTRING, 0,0);
}
//add new items
for( iCount = 0; iCount < 4; iCount++ )
{
strcpy(strNew, "");
strcat(strNew,"Window ID: ");
_itoa(iCount,buffer,10);
strcat(strNew,buffer);
_itoa(iRectCount[iCount],
strcat(strNew, " Figures Drawn: ");
strcat(strNew,buffer);
_itoa(GetThreadPriority(
strcat(strNew, " Priority: ");
strcat(strNew,buffer);
strcat(strNew, " Status: ");
if (iState[iCount]==ACTIVE) strcat(strNew,"ACTIVE");
else strcat(strNew,"SUSPENDED");
SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)(LPCTSTR)strNew);
}
SendMessage(hwndList, LB_SETCURSEL, lastSelection, 0);
UpdateWindow(hwndList);
return;
}
void ClearChildWindows(void)
{
return;
}
LRESULT WINAPI Main_WndProcChild
( HWND hWnd, // message address
UINT uMessage, // message type
WPARAM wParam, // message contents
LPARAM lParam ) // more contents
{
return( DefWindowProc(hWnd, uMessage, wParam, lParam) );
}
Заключение
В данной работе рассмотрены различные аспекты системного программирования с использованием API-функций в среде программирования Visual Studio 2008. Особенное внимание уделено управлению контролем прав доступа на файлы и папки, работе с сообщениями в консоли, сервисами и каналами.
Мы видим, что API-функции имеют достаточно сложный синтаксис. Сложность заключается как в строгом соблюдении типов параметров и количестве самих параметров, так и в необходимости использования дополнительных API-функций и даже отдельных приложений. Но, несмотря на их сложность, использование API-функций является наиболее эффективным способом разработки приложений вообще и практически необходимым способом разработки системных приложений в частности.
Использование API-функций дает разработчику большие возможности в управлении основными объектами операционной системы, такими как файлы, процессы, коммуникации (как сетевые, так и коммуникации между программами), приложения и др.
В связи с этим можно сделать следующие основные выводы:
1. API-функции представляют собой необходимые средства при проектировании системных приложений самого разного характера
2. Использование API-функций напрямую значительно повышает качество и скорость выполнения приложений
3. Рассмотрение различных API-функций способствует пониманию принципов работы самой операционной системы
1. А. Побегайло «Системное программирование в Windows». – СПб.: БХВ-Петербург
2. Н. Культин «С/С++ в задачах и примерах». – СПб 2004.
3. Ю.А. Аляев, О.А. Козлов «Алгоритмизация и языки программирования Pascal, C++, Visual Basic». – М 2004.
4. Б.И. Березин, С.Б. Березин «Начальный курс С и С++». – М 2004.
5. http://www.sources.ru/