حماية البرامج

    تمر دردشة الساحة الخاصة بالمتصفح والموبايل بفترة صيانة دورية هذا ونعتذر للجميع على الإنقطاع المؤقت بإمكانكم المشاركة في المنتدى لحين عودتها :)

    • حماية البرامج

      حماية البرامج


      حماية البرامج بغرض عدم النسخ بجانب التشريعات هو احد اهتمامات المبرمجين وقد كانت الحماية في السابق تتم عن طريق عمل فورمات لاحد قطاعات القرص المرن ويقوم البرنامج بالكشف على القطاع التالف مباشرة فاءذا وجده تالفا يقوم البرنامج بالعمل والعكس من ذلك يتوقف عن العمل وانا اقصد بالكشف مباشرة على القطاع ان القطاعات التالفة يحدد نظام التشغيل رقمها في جدول تواجد الملفات ، لو استخدمت برنامج ليقوم بتحديد هذا القطاع في جدول تواجد الملفات على انه قطاع تالف (مثل برنامج نورتون) لن يعمل البرنامج المحمي في هذه الحالة لان القطاع المطلوب تم تحديده على انه تالف ليبتعد نظام التشغيل عنه عند الكتابه ولكن عندما يتجه اليه البرنامج مباشرة سيستطيع التعامل معه وبالتالي ليس قطاع تالف كما يريد وتكون هذه العملية غير مفيده في كسر حماية البرنامج وعلى حد علمي وبعد ان اطلعت على كتب البرمجه المتقدمة التي تصدرها ميكروسوفت حتى دوس 6 لم اجد قاطع (القواطع هي مكونات الدوس الرئيسيه التي تستدعيها البرامج وتقوم بعملياتها عن طريقها فليس في استطاعة برنامج التعامل مع الاقراص مباشرة ولكن يقوم البرنامج بصف بياناته ليقوم نظام التشغيل عن طريق هذه القواطع بانجاز المطلوب) اقول لم اجد قاطع او دالة تقوم بعمل فورمات لقطاع واحد فقط ولكن يوجد من يقوم بعمل فورمات لعدة قطاعات مرة واحدة اي مسار او تراك وبالتالي قرص كامل.

      وكان ناسخو البرامج يستخدمون برامج تقوم بنسخ القرص كما هو اي تقليد نسخة من الاصل عكس عملية النسخ العادي والمحترفون منهم كانوا يدخلوا الى البرنامج الاصلي لتحويل مسار الكشف عن القطاع التالف وبالتلي تقوم بنسخ البرنامج بالطرق العادية وعندها يعمل بكل بساطة.

      اذا الهدف الرئيسي لاي برنامج محمي هو البحث عن شئ يميز به نسخته الاصلية

      الحماية بالدنجل

      آخر برنامجين اطلعت على طريقة حمايتهم بالدنجل (بالطبع لن اذكر اسمائهم) اختلفت فيهم طرق الحماية وان تشابه جوهر الموضوع وهو التأكد من وجود دنجل.

      ادوات العمل

      1- البرنامج المطلوب فحصه

      2- برنامج مراقبة لنظام التشغيل ليراقب سلوك البرنامج عند العمل ماذا يستدعي من مكتبات ربط ديناميكيه اثناء عمله وهل هذه المكتبات خاصه بالبرنامج ام عامه للوندوز (بالطبع يتجه نظرك الى مكتباته الخاصه) وهل يقوم بكتابة ملفات لتكن بمثابة بصمة تتأكد منها بقية ملفاته التي تستدعى.

      3- برنامج تفكيك او (ديس أسمبلر) لاعادة البرنامج من لغة الآله الى لغة التجميع (لاحظ ان هذه العملية تسمى هندسة معكوسة وهي ممنوعة قانونا لكل او جزء من البرنامج)

      4- محرر نصوص ثنائي (لس هن نوع محررات النصوص العادية التي تكتب بها خطاب مثلا) ولكن تعدل ارقام الملف التنفيذي بعد الاستقرار على التعديل.

      5- المام بسيط بعدد من اوامر لغة الاسمبلي.

      البرنامج الاول السابق التحدث عنه

      وجد ان البرنامج عبارة عن ملف صغير فيه روتينات التأكد من الدنجل ثم يقوم البرنامج بتشغيل البرنامج الرئيسي سواء وجد الدنجل ام لم يجده ولكن عند العثور على الدنجل يعمل البرنامج بصورة طبيعية والعكس يعمل البرنامج كنسخة عرض مجانية وقد وضعوا عدة روتينات في منتهى الذكاء سوف اوضحها لك.

      1- في الثانية الاولى لتشغيل اي برنامج يصدر عدد هائل جدا من الاوامر بلغة الاسمبلي الصعبة الالمام بمنطقها وذلك عند نقرك بالماوس على ايكون البرنامج وانت لا تدري ماذا يحدث وبالتالي على هذا الشخص ان يبحث عن هدفه مباشرة دون الدخول في عدة الاف من الاوامر اي منطقة الرسالة التي تظهر بأن الدنجل غير موجود (هل تدري ماذا فعل المبرمجين) لقد وضعوا الكشف على الدنجل مبكرا جدا وليس في هذه المنطقة وبالتالي يجعلوا من يسطوا عليهم يدور حول نفسه ويبحث عن شئ ضاع منه في الظلام في منطقة مضاءة لمجرد وجود ضؤ فيها.

      2- عند العثور على روتينات الكشف على الدنجل وفكر احدهم ان يقوم بوضع اوامر للقفز عليها وعدم الدخول فيها وبالتالي تخطي الدنجل ليعمل البرنامج بدون دنجل قد تنجح مع احد البرامج ولكن مع هذا البرنامج قام هؤلاء الاذكياء بجعل البرنامج يقوم بتكوين عدة بارامترات لا تتكون الا داخل روتين الكشف على الدنجل ووجوده ليقوم البرنامج الصغير بتمرير هذه البارامترات الى البرنامج الرئيسي لكي يعمل واذا لم تمرر هذه البارامترات لن يعمل البرنامج واذا قام احدهم بتخطي الدنجل لن تكون هذه البارامترات وسابين لك الاوامر التي وضعت لتمرير هذه البارامترات وقد قام هاكر كندي بمعرفة هذه البارامترات وعمل برنامج صغير جدا يمرر هذه البرامترات الى البرنامج الرئيسي وبالتالي كسر البرنامج المذكور.

      دالة تشغيل البرنامج وتمرير البارامترات كما صممتها ميكروسوفت



      CreateProcess

      The CreateProcess function creates a new process and its primary thread.

      The new process executes the specified executable file.

      BOOL CreateProcess(





      LPCTSTR lpApplicationName,





      // pointer to name of executable module





      LPTSTR lpCommandLine, // pointer to command line string





      LPSECURITY_ATTRIBUTES lpProcessAttributes,

      // process security attributes

      LPSECURITY_ATTRIBUTES lpThreadAttributes,

      // thread security attributes





      BOOL bInheritHandles, // handle inheritance flag





      DWORD dwCreationFlags, // creation flags





      LPVOID lpEnvironment, // pointer to new environment block





      LPCTSTR lpCurrentDirectory,

      // pointer to current directory name





      LPSTARTUPINFO lpStartupInfo, // pointer to STARTUPINFO





      LPPROCESS_INFORMATION lpProcessInformation

      // pointer to PROCESS_INFORMATION

      );





      Parameters

      lpApplicationName

      Pointer to a null-terminated string that specifies the module to execute.

      The string can specify the full path and filename of the module to execute or it can specify a

      partial name. In the case of a partial name, the function uses the current drive and current directory

      to complete the specification.

      The lpApplicationName parameter can be NULL. In that case, the module name must be the first white

      space-delimited token in the lpCommandLine string. If you are using a long filename that contains a space,

      use quoted strings to indicate where the filename ends and the arguments begin, otherwise, the filename is

      ambiguous. For example, consider the string "c:\program files\sub dir\program name". This string can be interpreted

      in a number of ways. The system tries the possibilities in the following order:

      c:\program.exe files\sub dir\program name

      c:\program files\sub.exe dir\program name

      c:\program files\sub dir\program.exe name

      c:\program files\sub dir\program name.exe

      The specified module can be a Win32-based application. It can be some other type of module (for example,

      MS-DOS or OS/2) if the appropriate subsystem is available on the local computer.

      Windows NT: If the executable module is a 16-bit application, lpApplicationName should be NULL, and the

      string pointed to by lpCommandLine should specify the executable module. A 16-bit application is one that

      executes as a VDM or WOW process.

      lpCommandLine

      Pointer to a null-terminated string that specifies the command line to execute. The system adds a null character

      to the command line, trimming the string if necessary, to indicate which file was actually used.

      The lpCommandLine parameter can be NULL. In that case, the function uses the string pointed to by lpApplication

      name as the command line.

      If both lpApplicationName and lpCommandLine are non-NULL, *lpApplicationName specifies the module to execute,

      and *lpCommandLine specifies the command line. The new process can use GetCommandLine to retrieve the entire

      command line. C runtime processes can use the argc and argv arguments.

      If lpApplicationName is NULL, the first white space-delimited token of the command line specifies the module name.

      If you are using a long filename that contains a space, use quoted strings to indicate where the filename ends and the

      arguments begin (see the explanation for the lpApplicationName parameter). If the filename does not contain an extension, .

      EXE is assumed. If the filename ends in a period (.) with no extension, or the filename contains a path, .EXE is not appended.

      If the filename does not contain a directory path, the system searches for the executable file in the following sequence:

      1. The directory from which the application loaded.

      2. The current directory for the parent process.

      3. Windows 95 and Windows 98: The Windows system directory. Use the GetSystemDirectory function to get the

      of this directory.

      Windows NT: The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory.

      The name of this directory is SYSTEM32.

      4. Windows NT: The 16-bit Windows system directory. There is no Win32 function that obtains the path of this directory,

      but it is searched. The name of this directory is SYSTEM.

      5. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.

      6. The directories that are listed in the PATH environment variable.

      If the process to be created is an MS-DOS - based or 16-bit Windows-based application, lpCommandLine should be a full

      command line in which the first element is the application name. Because this also works well for Win32-based applications,

      it is the most robust way to set lpCommandLine.

      lpProcessAttributes

      Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes.

      If lpProcessAttributes is NULL, the handle cannot be inherited.

      Windows NT: The lpSecurityDescriptor member of the structure specifies a security descriptor for the new process.

      If lpProcessAttributes is NULL, the process gets a default security descriptor.

      lpThreadAttributes

      Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes.

      If lpThreadAttributes is NULL, the handle cannot be inherited.

      Windows NT: The lpSecurityDescriptor member of the structure specifies a security descriptor for the main thread.

      If lpThreadAttributes is NULL, the thread gets a default security descriptor.

      bInheritHandles

      Indicates whether the new process inherits handles from the calling process. If TRUE, each inheritable open handle

      in the calling process is inherited by the new process. Inherited handles have the same value and access privileges

      as the original handles.

      dwCreationFlags

      Specifies additional flags that control the priority class and the creation of the process. The following creation flags

      can be specified in any combination, except as noted:

      Value

      Meaning

      CREATE_DEFAULT_ERROR_MODE



      The new process does not inherit the error mode of the calling process. Instead, CreateProcess gives the new process

      he current default error mode. An application sets the current default error mode by calling SetErrorMode.

      This flag is particularly useful for multi-threaded shell applications that run with hard errors disabled.

      The default behavior for CreateProcess is for the new process to inherit the error mode of the caller. Setting this flag

      changes that default behavior.

      CREATE_NEW_CONSOLE



      The new process has a new console, instead of inheriting the parent's console. This flag cannot be used with the

      DETACHED_PROCESS flag.

      CREATE_NEW_PROCESS_GROUP



      The new process is the root process of a new process group. The process group includes all processes that

      descendants of this root process. The process identifier of the new process group is the same as the process identifier,

      which is returned in the lpProcessInformation parameter. Process groups are used by the GenerateConsoleCtrlEvent

      function to enable sending a ctrl+c or ctrl+break signal to a group of console processes.

      CREATE_SEPARATE_WOW_VDM



      Windows NT: This flag is valid only when starting a 16-bit Windows-based application. If set, the new process is run in

      a private Virtual DOS Machine (VDM). By default, all 16-bit Windows-based applications are run as threads in a single,

      shared VDM. The advantage of running separately is that a crash only kills the single VDM; any other programs running

      in distinct VDMs continue to function normally. Also, 16-bit Windows-based applications that are run in separate VDMs

      have separate input queues. That means that if one application hangs momentarily, applications in separate VDMs continue

      to receive input. The disadvantage of running separately is that it takes significantly more memory to do so. You should use

      this flag only if the user requests that 16-bit applications should run in them own VDM.

      CREATE_SHARED_WOW_VDM



      Windows NT: The flag is valid only when starting a 16-bit Windows-based application. If the DefaultSeparateVDM

      in the Windows section of WIN.INI is TRUE, this flag causes the CreateProcess function to override the switch and run the

      new process in the shared Virtual DOS Machine.

      CREATE_SUSPENDED



      The primary thread of the new process is created in a suspended state, and does not run until the ResumeThread function is called.

      CREATE_UNICODE_ENVIRONMENT



      If set, the environment block pointed to by lpEnvironment uses Unicode characters. If clear, the environment block uses

      ANSI characters.

      DEBUG_PROCESS



      If this flag is set, the calling process is treated as a debugger, and the new process is a process being debugged. The system

      notifies the debugger of all debug events that occur in the process being debugged.

      If you create a process with this flag set, only the calling thread (the thread that called CreateProcess) can call the

      WaitForDebugEvent function.

      Windows 95 and Windows 98: This flag is not valid if the new process is a 16-bit application.

      DEBUG_ONLY_THIS_PROCESS



      If not set and the calling process is being debugged, the new process becomes another process being debugged by the

      calling process's debugger. If the calling process is not a process being debugged, no debugging-related actions occur.

      DETACHED_PROCESS



      For console processes, the new process does not have access to the console of the parent process. The new process can

      call the AllocConsole function at a later time to create a new console. This flag cannot be used with the CREATE_NEW_CONSOLE flag.



      The dwCreationFlags parameter also controls the new process's priority class, which is used in determining the scheduling

      priorities of the process's threads. If none of the following priority class flags is specified, the priority class defaults to

      NORMAL_PRIORITY_CLASS unless the priority class of the creating process is IDLE_PRIORITY_CLASS. In this case

      the default priority class of the child process is IDLE_PRIORITY_CLASS. One of the following flags can be specified:

      Priority

      Meaning

      HIGH_PRIORITY_CLASS

      Indicates a process that performs time-critical tasks that must be executed immediately for it to run correctly. The threads

      of a high-priority class process preempt the threads of normal-priority or idle-priority class processes. An example is the

      Task List, which must respond quickly when called by the user, regardless of the load on the system. Use extreme care

      when using the high-priority class, because a high-priority class CPU-bound application can use nearly all available cycles.

      IDLE_PRIORITY_CLASS

      Indicates a process whose threads run only when the system is idle and are preempted by the threads of any process

      running in a higher priority class. An example is a screen saver. The idle priority class is inherited by child processes.

      NORMAL_PRIORITY_CLASS

      Indicates a normal process with no special scheduling needs.

      REALTIME_PRIORITY_CLASS

      Indicates a process that has the highest possible priority. The threads of a real-time priority class process preempt the

      threads of all other processes, including operating system processes performing important tasks. For example, a real-time

      process that executes for more than a very brief interval can cause disk caches not to flush or cause the mouse to be unresponsive.



      lpEnvironment

      Pointer to an environment block for the new process. If this parameter is NULL, the new process uses the environment

      of the calling process.

      An environment block consists of a null-terminated block of null-terminated strings. Each string is in the form:

      name=value







      Because the equal sign is used as a separator, it must not be used in the name of an environment variable.

      If an application provides an environment block, rather than passing NULL for this parameter, the current directory

      information of the system drives is not automatically propagated to the new process. For a discussion of this situation

      and how to handle it, see the following Remarks section.

      An environment block can contain Unicode or ANSI characters. If the environment block pointed to by lpEnvironment

      contains Unicode characters, the dwCreationFlags field's CREATE_UNICODE_ENVIRONMENT flag will be set. If the

      block contains ANSI characters, that flag will be clear.

      Note that an ANSI environment block is terminated by two zero bytes: one for the last string, one more to terminate the

      block. A Unicode environment block is terminated by four zero bytes: two for the last string, two more to terminate the block.

      lpCurrentDirectory

      Pointer to a null-terminated string that specifies the current drive and directory for the child process. The string must be

      a full path and filename that includes a drive letter. If this parameter is NULL, the new process is created with the same

      current drive and directory as the calling process. This option is provided primarily for shells that need to start an a

      pplication and specify its initial drive and working directory.

      lpStartupInfo

      Pointer to a STARTUPINFO structure that specifies how the main window for the new process should appear.

      lpProcessInformation

      Pointer to a PROCESS_INFORMATION structure that receives identification information about the new process.

      Return Values

      If the function succeeds, the return value is nonzero.

      If the function fails, the return value is zero. To get extended error information, call GetLastError.

      Remarks

      The CreateProcess function is used to run a new program. The WinExec and LoadModule functions are still available,

      but they are implemented as calls to CreateProcess.

      In addition to creating a process, CreateProcess also creates a thread object. The thread is created with an initial stack

      whose size is described in the image header of the specified program's executable file. The thread begins execution at the

      image's entry point.

      The new process and the new thread handles are created with full access rights. For either handle, if a security descriptor

      s not provided, the handle can be used in any function that requires an object handle to that type. When a security descriptor

      is provided, an access check is performed on all subsequent uses of the handle before access is granted. If the access check

      denies access, the requesting process is not able to use the handle to gain access to the thread.

      The process is assigned a 32-bit process identifier. The identifier is valid until the process terminates. It can be used to identify

      the process, or specified in the OpenProcess function to open a handle to the process. The initial thread in the process is also

      assigned a 32-bit thread identifier. The identifier is valid until the thread terminates and can be used to uniquely identify

      thread within the system. These identifiers are returned in the PROCESS_INFORMATION structure.

      When specifying an application name in the lpApplicationName or lpCommandLine strings, it doesn't matter whether the

      application name includes the filename extension, with one exception: an MS-DOS – based or Windows-based application

      whose filename extension is .COM must include the .COM extension.

      The calling thread can use the WaitForInputIdle function to wait until the new process has finished its initialization and is

      waiting for user input with no input pending. This can be useful for synchronization between parent and child processes,

      because CreateProcess returns without waiting for the new process to finish its initialization. For example, the creating process

      would use WaitForInputIdle before trying to find a window associated with the new process.

      The preferred way to shut down a process is by using the ExitProcess function, because this function notifies all

      dynamic-link libraries (DLLs) attached to the process of the approaching termination. Other means of shutting down

      a process do not notify the attached DLLs. Note that when a thread calls ExitProcess, other threads of the process are

      terminated without an opportunity to execute any additional code (including the thread termination code of attached DLLs).

      ExitProcess, ExitThread, CreateThread, CreateRemoteThread, and a process that is starting (as the result of a call by

      CreateProcess) are serialized between each other within a process. Only one of these events can happen in an address

      space at a time. This means the following restrictions hold:

      During process startup and DLL initialization routines, new threads can be created, but they do not begin execution

      until DLL initialization is done for the process.

      Only one thread in a process can be in a DLL initialization or detach routine at a time.

      The ExitProcess function does not return until no threads are in their DLL initialization or detach routines.

      The created process remains in the system until all threads within the process have terminated and all handles to the

      process and any of its threads have been closed through calls to CloseHandle. The handles for both the process and the

      main thread must be closed through calls to CloseHandle. If these handles are not needed, it is best to close them

      immediately after the process is created.

      When the last thread in a process terminates, the following events occur:

      All objects opened by the process are implicitly closed.

      The process's termination status (which is returned by GetExitCodeProcess) changes from its initial value of STILL_

      ACTIVE to the termination status of the last thread to terminate.

      The thread object of the main thread is set to the signaled state, satisfying any threads that were waiting on the object.

      The process object is set to the signaled state, satisfying any threads that were waiting on the object.

      If the current directory on drive C is \MSVC\MFC, there is an environment variable called =C: whose value is C:\MSVC\MFC.

      As noted in the previous description of lpEnvironment, such current directory information for a system's drives does not

      automatically propagate to a new process when the CreateProcess function's lpEnvironment parameter is non-NULL.

      An application must manually pass the current directory information to the new process. To do so, the application must

      explicitly create the =X environment variable strings, get them into alphabetical order (because the system uses a sorted

      environment), and then put them into the environment block specified by lpEnvironment. Typically, they will go at the front

      of the environment block, due to the previously mentioned environment block sorting.

      One way to obtain the current directory variable for a drive X is to call GetFullPathName("X:",. .). That avoids an application

      having to scan the environment block. If the full path returned is X:\, there is no need to pass that value on as environment data,

      since the root directory is the default current directory for drive X of a new process.

      The handle returned by the CreateProcess function has PROCESS_ALL_ACCESS access to the process object.

      The current directory specified by the lpcurrentDirectory parameter is the current directory for the child process.

      The current directory specified in item 2 under the lpCommandLine parameter is the current directory for the parent process.

      Windows NT: When a process is created with CREATE_NEW_PROCESS_GROUP specified, an implicit call

      to SetConsoleCtrlHandler(NULL,TRUE) is made on behalf of the new process; this means that the new process

      has ctrl+c disabled. This lets good shells handle ctrl+c themselves, and selectively pass that signal on to

      sub-processes. ctrl+break is not disabled, and may be used to interrupt the process/process group.

      Windows CE: The name of the module to execute must be specified by the lpApplicationName parameter.

      Windows CE does not support passing NULL for lpApplicationName. The execution module cannot be specified in

      the command line string.

      Windows CE searches the directories indicated by the lpApplicationName parameter in the following order:

      The root of the PC Card if it exists

      The windows (\windows) directory

      The root (\ ) directory of the device

      The following parameters are not supported and require the following settings:

      lpProcessAttributes must be NULL

      lpThreadAttributes must be NULL

      bInheritHandles must be FALSE

      lpEnvironment must be NULL

      lpCurrentDirectory must be NULL

      lpStartupInfo must be NULL

      For Windows CE version 1.0, the dwCreationFlags parameter only supports the following values: CREATE_SUSPENDED and zero.

      For Windows CE version 2.0, the dwCreationFlags parameter only supports the following values: CREATE_SUSPENDED,

      DEBUG_PROCESS, DEBUG_ONLY_THIS_PROCESS and zero.

      Priority classes for processes are not supported.

      The loader has a limited search path.




      Step 2. Adapting the OEMDONGL.C Source Code

      The DDK supplied with the DDK has VxD support for the following IR devices:

      ACTiSYS ACT-200L Infrared Wireless Interface (ACT200L.VXD)

      ACTiSYS ACT-220L Infrared Wireless Interface (ACT220L.VXD)

      Adaptec(tm) AIRport APA-9320 External Infrared Adapter; this adapter is also called the Adaptec AIRport 2000 (ADAPTEC.VXD)

      Adaptec AIRport 1000 (ADAPTEC.VXD)

      AMP PhasIR Serial Adapter (CRYSTAL.VXD)

      Extended Systems JetEye PC Infrared PC Interface, ESI-9680 (ESI.VXD)

      Parallax IR Adapter LiteLink PRA9500A (PARALLAX.VXD)

      If your IR device is not one listed above or is not compatible with one of those devices, then you must modify the OEMDONGL.C

      source code to support your device and create a new VxD. In order to produce a VxD that works with the generic serial IrFramer to

      support your device, adapt the OEMDONGL.C sample source code to your dongle hardware, compile it, and link it to DONGLE.LIB

      and CVXDCTRL.ASM.

      Establishing the Microsoft Infrared Communications for Windows 95 Build Environment

      The first step in creating your own IrFramer is to establish a build environment. In order to build binary files that are comparable

      with the current shipping versions, you will need to use the same tools that were used to build the shipping versions. The build

      environment includes a C Compiler, Assembler, Linker, include files and libraries - all of the tools necessary to build executable

      modules from the sample source code provided in this DDK.

      If you install both the Win32 SDK and Windows 95 DDK on your development system, then you will have all the header files

      and libraries you need. You also have to install a set of compilers and an assembler.

      Follow this sequence of steps in establishing your build environment:

      1. Install the compilers and assembler. The following are all necessary: Microsoft Visual C, version 2.x (for 32-bit development),

      Microsoft Visual C, version 1.5x (for 16-bit development), and Microsoft Assembler, version 6.11c.

      2. Next, install the Win32 SDK.

      3. Lastly, install the Windows 95 DDK.

      Introducing the Sample Source Code

      The sample source code for your VxD is in the DDK subdirectory. The source code modules in the DDK subdirectory that

      you must modify are described in the following table:

      File

      Description

      Comment

      OEMDONGL.C

      Contains the OEMDongleTable which is an array of DONGLE_TYPE structures that list the supported dongles and their

      support functions.

      Contains the OEMDongleTableLen variable that specifies the number of dongles that support is being added for.

      Contains the functions to support initializing the dongle, setting the dongle's speed (from 2400 baud to 115,200 baud),

      and turning off the dongle.

      The functions currently in OEMDONGL.C are for the ACTiSYS 200L dongle, except the content of the OEMDongleTable

      array and the names of the type_Init, type_SetSpeed, and type_Deinit functions have been changed to highlight the parts

      of the code you must change. Note that the name of the OEMDongleTable array and the OEMDongleTableLen variable must

      not be changed. More details about this are given below.

      CVXDCTRL.ASM

      Wrapper that can be linked with OEMDONGL.C to produce a dynamically loadable VxD.

      The sample CVXDCTRL.ASM source code is for the ACTiSYS 200L dongle. You will have to edit this code to establish the

      name of your VxD.



      Editing the OEMDongleTable Array and Registry

      To add a dongle type that can be used by the framer, add the dongle type's identifying string and pointers to its type_Init,

      type_SetSpeed, and type_Deinit functions to the OEMdongleTable array. The sample source code that defines the array in

      OEMDONGLE.C looks like this:



      DONGLE_TYPE OEMDongleTable[] =

      {

      {"OEM", OEM_Init, OEM_SetSpeed, OEM_Deinit }

      };



      U32 OEMDongleTableLen = (sizeof(OEMDongleTable)/sizeof(DONGLE_TYPE));



      The DONGLE_TYPE structure is defined in _DONGLE.H:



      // Data structure used to hold Dongle information

      typedef struct _DONGLE_TYPE

      {

      char* typeName; // Name of dongle in the registry

      IRLAPFRM_DONGLE_INIT init; // Pointer to init function

      IRLAPFRM_DONGLE_SET set; // Pointer to setSpeed function

      IRLAPFRM_DONGLE_DEINIT deinit; // Pointer to deinit function

      } DONGLE_TYPE, *PDONGLE_TYPE;

      So, for example, if your IR dongle device model is named the REDEYE-88 you could edit the OEMDongleTable

      array in OEMDONGLE.C to look like this:



      DONGLE_TYPE OEMDongleTable[] =

      {

      {"RED88", RED88_Init, RED88_SetSpeed, RED88_Deinit}

      };

      You also have to write the name of your dongle type into the registry. The framer gets the names of the dongle

      types installed on a Windows 95 computer by reading the registry. To add your own dongle type name to the

      registry during development, you will have to adapt the INFRARED.INF file shipped with the DDK or use the

      Regedit utility. Continuing with the example, your dongle type name is "RED88." At the registry path

      HKEY_LOCAL_MACHINE\Enum\Infrared\Framer add the following key and value:



      DongleType="RED88"

      You must also add the name of your VxD to the registry. For example, if the name of your VxD is

      RED88.VXD, then at the registry path HKEY_LOCAL_MACHINE\Enum\Infrared\Framer you must add the

      following key and value:



      SpeedDriver="RED88.VXD"

      For information on editing the INFRARED.INF file to accomplish these changes to the registry when your

      VxD is installed using Setup, see Creating an Installation Diskette and Installing the IR Communications Software.

      Adapting the Interface Exposed to the IrFramer

      The interface that a specific dongle-type source code module exposes to the generic IrFramer (through the

      function pointer table in OEMDONGLE.C) can have three functions:

      Function

      Description

      type_Init

      Initializes your IR hardware and returns the capabilities mask.

      type_SetSpeed

      Sets the send and receive speed of your IR hardware and sets VCOMM to handle that speed.

      type_Deinit

      Powers down or deinitializes your IR hardware.



      Using the Available Support Functions

      A number of functions are available to the OEMDONGL.C module. You have the option of using the

      VCOMM functions directly and/or indirectly through the functions listed below. It is strongly recommended

      that you not use the VCOMM functions directly for two-way communication with the dongle. Use the provided

      functions wherever applicable. The function prototypes are in _DONGLE.H and are shown below:



      //************************************************************************

      //

      // Function prototypes of utility functions that should be used by

      // dongle functions.







      // IrLapFrmSetSpeed will set the speed of the UART to the given speed

      // using VCOMM calls.







      BOOL IrLapFrmSetSpeed(U32 hCom, LM_BAUD_RATE speed);







      // IrLapFrmReadChar is used to read a character from the UART using VCOMM calls

      // It assumes that events are turned off so it polls. If no character is read in

      // in 12 ms it will return FALSE. If a VCOMM error occurs it will return false.

      // If it returns TRUE the character read is placed in the variable pointed to by

      // c.







      BOOL IrLapFrmReadChar(U32 hCom, PU8 c);







      // IrLapFrmWriteChar is used to write a character to the UART using VCOMM calls.

      // It returns TRUE if successful otherwise it returns FALSE.







      BOOL IrLapFrmWriteChar(U32 hCom, U8 c);







      // VMM_GetSystemTime returns the number of milliseconds since Windows started. It is

      // accurate to 1ms. This is the standard VMM call.







      UINT VMM_GetSystemTime( VOID );

      Adapting the type_Init Function

      The type_Init function is called by the framer to initialize your IR hardware and to get the dongle

      capabilities masks. When type_Init is called, the hCom (VCOMM handle) will be set for 9600 baud,

      8 data bits, no parity, and 1 stop bit. When type_Init returns, the dongle must be active and ready to

      receive and send data and the VCOMM handle must be set to 9600 baud, 8 data bits, no parity, and 1 stop bit.

      If the dongle cannot be initialized type_Init must return IRDA_STATUS_FAILED.

      The syntax of the function call is:



      BOOL type_Init(

      U32 hCom,

      PDONGLE_CAPABILITIES cap

      )

      type_Init assumes

      The hCom parameter identifies a port that has been opened and is set to 9600 baud, 8 data bits, no parity, and 1 stop bit.

      The framer has set no VCOMM event callbacks on the port so type_Init can send and receive characters without

      interference from the framer.

      The cap parameter points to the DONGLE_CAPABILITIES structure that type_Init returns to the framer; type_Init can,

      as an option, set bits in the masks that make up this structure to register Baud Rate, Minimum Turn Around Time,

      and Number of BOFs capabilities with the framer.

      The DONGLE_CAPABILITIES structure is defined in _DONGLE.H and is shown below:



      // DONGLE_CAPABILITIES - is a structure that contains the IrDA

      // capabilities a dongle can effect. The order of the elements in

      // this structure must be the same as those in the IRLAPFRM_CAPABILITIES

      // structure.







      typedef struct

      {

      U32 supportedSpeeds; // Supported speeds of the dongle

      U32 minTurnAroundTime; // Min turn around time on the dongle

      U32 additionalBOFs; // Additional BOFs required by the dongle.

      } DONGLE_CAPABILITIES, *PDONGLE_CAPABILITES;

      The meaning of the pattern of bit settings in the three capabilities bit masks is defined fully in Infrared Data

      Association Serial Infrared Link Access Protocol (IrLAP), but summary tables are presented here.

      Baud Rate

      The bit settings in the baud rate mask indicate the speed(s) at which the IR device can transmit over the data link:



      bit 0 =

      2400 bps (LSB, transmitted first)

      bit 1 =

      9600 bps

      bit 2 =

      19200 bps

      bit 3 =

      38400 bps

      bit 4 =

      57600 bps

      bit 5 =

      115200 bps

      bit 6 =

      reserved and must be set to 0

      bit 7 =

      reserved and must be set to 0



      Minimum Turn Around Time

      Minimum turn around time is the time delay required by the IR device from the time it receives the last byte

      from one device until it is ready to receive the first byte from another device.

      bit 0 =

      10 ms (LSB, transmitted first)

      bit 1 =

      5 ms

      bit 2 =

      1 ms

      bit 3 =

      0.5 ms

      bit 4 =

      0.1 ms

      bit 5 =

      0.05 ms

      bit 6 =

      0.01 ms

      bit 7 =

      0.005 ms



      Number of BOFs

      These bit settings indicate the number of additional flags needed at the beginning of every frame to provide a

      delay at the beginning of each frame for devices with long interrupt latency. The bit settings in this mask depend

      on the baud rate. See Infrared Data Association Serial Infrared Link Access Protocol (IrLAP) for all the different possible values.

      The following shows an example of adapting the OEMDONGLE.C sample source code function OEM_Init. The supportedSpeeds

      mask is set to support all speeds between 9600 baud and 115.2 baud and is set for a 1 ms turnaround, using the following code:



      #define CRYSTAL_SPEEDMASK 0x3F /*supported speeds 115.2Kbps->9600 Kbps*/

      #define CRYSTAL_MINTURN 0x00 /*0 turn around*/

      .

      .

      .

      //*********************************************************************

      BOOL OEM_Init(U32 hCom, PDONGLE_CAPABILITIES cap)

      {

      .

      .

      .







      cap->supportedSpeeds &= CRYSTAL_SPEEDMASK;

      .

      .

      .

      }

      Suppose your RED88 dongle only supports 9600, 19200, and 115200 baud. You can change the supportedSpeeds mask to

      reflect that by changing two lines of the sample code:



      #define RED88_SPEEDMASK 0x00000026

      .

      .

      .







      cap->supportedSpeeds &= RED88_SPEEDMASK;

      .

      .

      .

      Adapting the type_SetSpeed Function

      The type_SetSpeed function is called by the framer IRLAPFRM_SetSpeed function to set the send and receive speed

      of your IR hardware. type_SetSpeed must also set VCOMM to handle the new speed because IRLAPFRM_SetSpeed does not do that.

      The syntax of the type_SetSpeed function call is:



      BOOL type_SetSpeed(

      U32 hCom,

      LM_BAUD_RATE speed

      )

      type_SetSpeed can send and receive characters with no interference from the IR framer because IRLAPFRM_SetSpeed

      disables VCOMM event callbacks before it calls type_SetSpeed.

      type_SetSpeed can also assume that the framer will not reset the VCOMM speed setting. Therefore, when type_SetSpeed

      is called, the VCOMM speed setting is either the same as the last time type_SetSpeed set it, or 9600 baud immediately after

      a call to type_Init.

      When type_SetSpeed returns, the framer assumes it can start sending or receiving data at the new speed and restores the

      VCOMM event callbacks. If it fails to set the IR device speed or the VCOMM speed setting, type_SetSpeed must return IRDA_

      STATUS_FAILED.

      It is not particularly useful to make up an example here for the hypothetical RED88 dongle device. The convention that notifies

      each particular dongle device of a speed change differs from device to device. Two things to notice about the sample code, however, are:

      The IrLapFrmSetSpeed function in OEMDONGLE.C can be called from your type_SetSpeed function to set the UART to a new speed.

      VCOMM_EscapeCommFunction is used to set the dongle hardware into and out of command mode (see the ACT200LSetCommandMode

      and ACT200LClearCommandMode functions in OEMDONGL.C). Using the VCOMM functions is quite acceptable in this case.

      Adapting the type_Deinit Function

      The type_Deinit function is called to power down or otherwise deactivate your hardware. It is called by the framer just before it calls

      VCOMM_CloseComm to close the port.

      The type_Deinit function can send and receive characters with no interference from the IR framer because VCOMM event callbacks

      are disabled before the call to the dongle function.

      The syntax of the type_Deinit function call is:



      BOOL type_Deinit(

      U32 hCom

      )

      The OEM_Deinit function in OEMDONGL.C (which uses the Crystal chip in the ACTiSYS 200L as an IR device) does the following:

      Resets the IR device.

      Sets the speed to 9600 baud (the discovery speed).

      Puts the IR chip in low-power mode.

      Make sure the IR device is not in command mode.