[Mundo .NET] Construindo consoles de gerenciamento com MMC 3.0 e C#

March 24th, 2009

br Português
Olá,

Conforme citado no artigo Construindo consoles de gerenciamento com MMC 3.0 e C# publicado na edição de Abril/2009 da revista Mundo .NET segue abaixo o código fonte completo da console utilizada durante o artigo. Caso alguém tenha alguma dúvida me envie um e-mail ou coloque um comentário nesse post que eu terei o maior prazer em ajudar :)

-George

RevistaMundoNET.MMC.Exemplo.zip

usa English
Hello,

I have published an article about MMC development using C#. This article was published in the Mundo .NET magazine here at Brazil. You can download the source code used as example in this article below. If you have any questions, please post me a message or send me an e-mail that I will answer as soon as possible.

-George

RevistaMundoNET.MMC.Exemplo.zip

[Definitions] Linker and Loader

November 12th, 2008

“The basic job of any linker or loader is simple: It binds more abstract names to more concrete names, which permits programmers to write code using the more abstract names. For example, it takes a name written by a programmer such as getline and binds it to “the location 612 bytes from the beginning of the executable code in module iosys.” Or it may take a more abstract numeric address such as “the location 450 bytes beyond the beginning of the static data for this module” and bind it to a numeric address.”

Extracted from Linkers and Loaders

-George

[Definitions] Programming Language

November 11th, 2008

“Programming languages are notations for describing computations to people and to machines.”

Extracted from Compilers: Principles, Techniques, & Tools

-George

[Definitions] Compiler

November 11th, 2008

“Compiler is a program that can read a program in one language - the source language - and translate it into an equivalent program in another language - the target language.”

Extracted from Compilers: Principles, Techniques, & Tools

-George

[C] COFF Object Files Under the Hood

November 10th, 2008

COFF object files are the compiler´s output. They contain the processor dependent opcodes that describe the logic that you wrote in C. They also contain global variables, text strings, linker directives, debug information and others.

After you generate them you must use a tool called linker to merge them together into a single file to be deployed as EXE, DLL or SYS. During this post we will explore the details of these COFF object files.

Below you can see an UML class diagram showing the objetcs that a COFF object file contain or could contain.

This diagram shows that every COFF obect file has one symbol table and at least one section. Sections can have relocations, but it´s not mandatory (check the .debug$S section below).

To show you these details I will use the following code. This is a simple C program that allocate some bytes from the heap (exactly what malloc does) and then print a Hello World string with the address alllocated.

To create the COFF object file we must compile it. To do it use the following command line.

As I already said in my last post the /c parameter says to the compiler to just generate the object file and don´t call the linker automatically.

After you have compiled it you can use the dumpbin utility to check these details (this is the tool that I used to get these images). Just type the following command line to get these results:

dumpbin /all filename.obj

Based on the dumpbin output and in the UML diagram above, you can see that COFF object files are composed of sections. One of them is the .drectve section. This section contains command line parameters that the linker reads and uses during the linking phase. These parameters are interpreted as they are defined. As you can see below by default the compilation process inserts two parameters, /DEFAULTLIB:”LIBCMT” and /DEFAULTLIB: “OLDNAMES”. The purpose of these parameters are to provide the C Runtime libraries for use by the linker. LICBMT is the library that contains the static multi-thread version of the CRT. The OLDNAMES is a library that provides function names translations like malloc to _malloc.

Another section is the .debug$S. This section contains debug information that we can use later to debug problems with this code. There are three formats that Microsoft C/C++ compiler can generate, they are COFF, CodeView and Program Database. The following article describes these formats and use very well. I strongly recommend that you read it.

generating debug information with visual c++
http://www.debuginfo.com/articles/gendebuginfo.html

The .data section contains the global variables and strings used. As you can see in the image below the Hello World! %p\n is there. Why? Because the compiler when see strings declared this way will put them in this section. You will also see here global variables (variables declared outside a function).

The .text section is where your code lives. At the RAW DATA #4 section in the image below you can see a lot of hexadecimal numbers (55 8B EC 51 6A …). These numbers are the opcodes that the processor executes. For each assembly mnemonic (MOV, ADD, CALL, etc) we have an opcode defined on the Intel/AMD manuals.

If we disassembly the opcodes inside this section we will get the following assembly code (output from Windbg !uf command):

Basically what we have here is the function epilog (configure the stack for use), then we have the opcodes that define the logic that you wrote in C and to finish we have the function prolog (restore the stack as it was before this function was called). All these opcodes are executed sequentially by the processor. After an opcode is executed the EIP register is incremented to point to the next opcode to be executed. And this will repeat as long the processor has power supply.

To finish this post you can see below one of the most important things inside a COFF object file, the symbol table. This table contains every function or variable exported by this object file that other object files can use. It also defines every function or variable that this object file needs (this dependencies will be resolved later by the linker). These dependencies are contained in other object files or LIB files.

During my studies I faced a question about the linker process, so I sent an e-mail to Tim Roberts (he has a very deep knowledge about the compile and linking process and other things as well) about this question. Below you can see his answer. He explained it so well that I want to share with you all. Thanks Tim!

George Luiz Bittencourt wrote:
> …
> When I create two object files (test1.obj and test2.obj) and each one have a function with the same name (test) and then link them together I get the following error:
> *error LNK2005: _test already defined in test2.obj*
>
> I agree with this error because there are two distinct functions with the same name, but if I create a LIB file with the second object file (test2.obj) inside it and then link the first object file with this LIB I don´t get this error anymore.
>
> IMHO I would have to get this error too, because still there is two functions with the same name. Do you know if there is any special treatment in this situation?
>

Yes, there is a big difference.

When you specify an object file to the linker, that file is FORCED into your executable. It is fully included. When you specify a library file, the objects in that library are simply AVAILABLE for use. They are not loaded unless they are needed.

As the linker brings in each object file, it keeps track of the list of names that it has not been able to find. Each object file probably satisfies some of the names that were already on that list, and adds new names to the list. After all of the object files are forced in, then the linker starts scanning the libraries. If there is a module in the library that includes one of the unsatisfied names, the linker will bring in that module. Otherwise, it leaves it out.

That’s the whole point of a library: to offer a whole bunch of services, while not requiring programs to bulk up on a bunch of stuff they don’t need.

It’s still possible to get a LNK2005 when using a library. Say that my executable has functions called “aaa” and “bbb”, and it needs functions called “ccc” and “ddd”. Now, lets’s say I have a library called mylib.lib that includes four separate objects:

aaa.obj defines aaa
bbb.obj defines bbb
ccc.obj defines ccc
ddd.obj defines ddd

Here, there is no chance for a LNK2005. But, let’s say that I reorganize my sources to combine two functions:

aaa.obj defines aaa
bbb.obj defines bbb and ccc
ddd.obj defines ddd

Now, when the linker goes to find “ccc”, it will bring in “bbb.obj”.
However, that defines “bbb”, which is already defined in my program.
That will trigger a LNK2005 error.


Tim Roberts

BOOKS

  1. Linkers and Loaders
  2. Compilers: Principles, Techniques, & Tools

Hope it helped you!

-George

[C] Understanding How the Build Process Works

October 31st, 2008

Well, it´s a long time since my last post. I was a litle busy, but now I´m back.

C (in my humble opinnion) is the most powerfull structured language ever created. Why? Because it allows to work very closer to the hardware and I am a person that like to know how the things works under the hood and have control of the execution.

Have it said I´m planning to blog about a lot of subjects on native development, like C, CRT (AKA libc), linking, etc. To start this series of posts I am going to explain how the C build process works. To do that I will use the Microsoft C Compiler that comes with a lot of Microsoft products. Below you can see a list of Microsoft products that come with the C/C++ compiler.

  1. Windows SDK
  2. Windows WDK
  3. Visual Studio 2008
  4. Visual C++ 2008 Express Edition

Before we start let’s define some terms that  I will use during this blog.

  1. Build process: are the steps necessary to create an executable unit from the compilation units;
  2. Compilation units: are the input files that the build process takes to create an executable unit. These are the files (in C they usually have a .C extension) that contains the source code where you defined a logic to acomplish a task (or tasks) using a notation (in this case the C programming language);
  3. Executable unit: is the output of the build process. It could be an executable file (EXE), a library (DLL) or a driver (SYS). Later it will be loaded by an operating system component called loader;

To explain this process I will use the following code as example. This code is a simple Hello World example. When executed it will just display a Hello World string in console.

This is my compilation unit and I want to create an executable unit. Programs usually are composed of a set of compilation units (lots of .C files) and the build process merges them in other files (EXEs, DLLs, etc) that you can deploy.

The C build process is a set of three steps executed sequentially as you can see below. This image shows the command lines (red text) that you can use to see the output for every step. If you only calls cl.exe without any parameter it will execute all the steps and you will not see the output for each step. At least one time you should follow these steps to learn how it works. This knowledge will be helpfull when you have to debug a build error.

These steps are executed to create an executable unit that the operating system interprets at execution time (be it an EXE, DLL or SYS file). As you can see these three steps are implemented by two executables (cl.exe and link.exe). By default cl.exe executes link.exe automatically, unless you use the /c parameter.

  1. Preprocess: this is the first step in the build process and the cl.exe executable does the work. During this step the preprocessing directives (#include, #define, #if, #pragma, etc) are processed and a new temporary compilation unit is created. You can see the contents of this compilation unit using the command line cl /P <file.c>. When you execute this command line a file with .i extension will be created with the final compilation unit. This is the file that will be the input for the compiler. I usually use this parameter (/P) to debug problems with #defines, #includes, etc that can occur;
  2. Compile: this is the step where your compilation unit created earlier will be translated from C language to processor dependent opcodes and its is done by the cl.exe executable too. This step will generate an .OBJ file that conforms with the COFF file format (check reference 1 for details). If you don´t specifiy the /c parameter, cl.exe will automatically invoke link.exe to generate the executable unit. Even if you don’t specify this parameter an .OBJ file will be created on the filesystem. I used the parameter /TC because we must tell to compiler what is the language inside the .i file. This is only necessary when the file doesn´t have a .c or .cpp extension. So you must tell the compiler what is the language used to create this source. That´s what this parameter does. It says to treat every source file as coded in C language;
  3. Link: this is the final step in the build process and the link.exe executable is responsible for it. link.exe task is to merge all the object files created from step 2 into an executable unit for use. This executable unit will conform with the PE specification (check refence 1 for details). Usually applications are comprised of a set of .OBJ files and link.exe merges all them. Additionally link.exe uses .LIB files to create the import address table. This table will be the subject of a next post;

There are some other utilities that you can use during the build process (to troubleshoot problems or investigate the details). I focused on this post on the essential tools to create an executable unit on Windows, but I will post about this other tools soon. Below you can see a list of other tools that you can use.

  1. nmake.exe
  2. lib.exe
  3. ml.exe
  4. rc.exe
  5. dumpbin.exe
  6. editbin.exe

REFERENCES

  1. Microsoft Portable Executable and Common Object File Format Specification
    http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx

Hope it helped you.

-George

[SQL Server] Tracing your own events in SQL Server Profiler

June 17th, 2008

SQL Server Profiler provides ten custom events that you can use to trace custom events in your application. This post will show you how to use these custom events.

The first step is configure the trace to monitor the custom events that you will use. This step is acomplished at the Events Selection tab in the Trace Properties window. To select the custom events switch to this tab, check the Show all events option, scroll to User configurable, expand this event category and select the apropriate events that you want monitor. You can see below this configuration.

After you configured the trace proprerties click the Run button to start the trace capture.

The second step is trigger these events. To do that you have to use the sp_trace_generateevent stored procedure. You can see this stored procedure definition below.

sp_trace_generateevent [ @eventid = ] event_id
[ , [ @userinfo = ] ‘user_info’ ]
[ , [ @userdata = ] user_data ]

The first parameter, @eventid, must be a number between 82 and 91. The number 82 is the UserConfigurable:0 event, 83 is the UserConfigurable:1 event, and the remaining numbers follow this pattern.

The second parameter, @userinfo, is an optional parameter that you use to set the message to display in SQL Server Profiler. This parameter must be nvarchar(128).

The third and last parameter, @userdata, is the data for the event. This an optional varbinary(8000) parameter.

Below you can see an TS-SQL example showing how to trigger the User Configurable event number 1.

sp_trace_generateevent 82, N’user event number 1′

The image below shows the result of executing the TS-SQL command above.

That´s it! Hope it helped you!

-George

[Windows] Configuring Time Zone by User

June 17th, 2008

Mark Russinovich in his post The Case of the System Process CPU Spikes said that we could send to him our troubleshoot posts and maybe we could win a signed Windows Internals book.

I wrote the post below and sent to him. Two days after I received an e-mail from Mark! And I WON a book from him! And it was signed! Its a honor to me have a signed Windows Internals book! You can see a photo of his sign at the end of this post.

“One of my customers was having some problems when printing invoices from branches with different time zones. The branches access the system through Citrix Presentation Server (CPS) and CPS has a feature that maps the time zone from the client to the server. Unfortunately my client can´t guarantee that his branches are using the correct time zone (they access CPS by thin clients) and he wanted to configure the time zone by user in Windows 2003.

Based on another troubleshootings I knew that Citrix has a DLL called tzhook.dll and by the name I suspected that the meaning of the name is time zone hook. To confirm that I ran Notepad and Process Explorer in a CPS session and looked the DLLs mapped into the process address space. tzhook.dll was there and the description of image file is “Citrix Time Zone Hook DLL”.

I was right, tzhook.dll really means time zone hook (see the image below) and is mapped into every process address space hooking the calls for date and time APIs.

The next question was “How tzhook.dll determines the time zone of the client?”

To answer that I enabled the Time Zone redirection in my Citrix farm and opened a new session. After that I ran Process Monitor inside this session and set the filter to monitor only notepad processes. I started notepad and hit the F5 key to insert the current date and time information (see image below). Now I got a full trace of the tzhook.dll activities.

I started looking the Process Monitor trace from top to bottom. I first noticed the following line:

To confirm that this operation was started by the tzhook.dll I right clicked this entry, selected the Properties and choose the Stack tab. The image below appeared and I confirmed that tzhook.dll has queried this registry key.

Humm, so tzhook.dll is querying some values on the HKCU hive. I right clicked this entry again and selected the Jump to action and regedit appeared with the following values.

The values’ names suggests what the purpose of which one is and the TZI value is a time zone structure that Windows uses to represent time zone information (I knew that because I developed an utility to change this structure some time ago).

Now I had all the information that I needed to solve this issue. I developed a C# application that is executed before any user application in a Citrix session and this application queries an attribute (defined by the customer) in Active Directory. Based on this information the application writes the values on the registry key above accordingly to simulate that time zone. The tzhook.dll does the rest.

One more issue solved with the help of Sysinternals awesome tools!”

Thank you Mark Russinovich! Keep the great work!

-George

[Oracle] Poor Exception Design at ODAC

June 11th, 2008

Two weeks ago one of my coworkers was installing a web application on IIS 7.0 and he was getting the Oracle error below.


The error message says that ODAC is not compatible with the Oracle client installed. He installed all the components that he thought necessary and ODAC still didn’t work. He asked for my help and to figure out what was really going on I started analyzing the call stack to determine why ODAC threw that exception.

The last stack frame in the call stack is the method that threw the exception. To determine why this method threw that exception I ran Lutz Roeder Reflector for .NET, openned ODAC assembly and navigated to Oracle.DataAccess.Client.OracleInit.Initialize() method.

After a litle review I realized that the exception was being throw at the below point.

try

{

    errCode = OpsInit.CheckVersionCompatibility(assemblyVersion);

    if (errCode != 0)

    {

        throw new OracleException(errCode);

    }

}

catch

{

    throw new OracleException(ErrRes.INIT_DLL_VERSION_MISMATCH);

}

As you can see ODAC throws an OracleException exception with the message “The provider is not compatible with the version of Oracle client” (this message is in the resource file embedded in the assembly) when Oracle client version is not supported by ODAC. OK, but how ODAC determines the Oracle client version installed? ODAC calls the OpsInit.CheckVersionCompatibility() static method and based on the return value throw the exception or not. I delved into this method and found that it is an interop for a function in OraOps10w DLL.

[DllImport("OraOps10w.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]

public static extern int CheckVersionCompatibility(string version);

I searched for this DLL in the server and didn’t find it. To confirm that the web application was trying to load this DLL I ran Process Monitor, filtered it to monitor only w3wp.exe processes and refreshed the web page. As you can see below w3wp.exe tried to load this DLL but didn’t find it. So CLR was throwing an DllNotFoundException and the return value check was never processed.


So ODAC is doing an interop and they assume that the necessary DLL will be always present on the server. They made this call inside a try catch block and in the catch block they throw the exception with the error message. The message says that the Oracle client installed is not compatible with ODAC. How can they say it if they didn´t successfully determine the Oracle client version installed?
In my opinnion they have to throw another exception with another message. A more concise message with the real problem. The message could be “The provider requires at least Oracle client version XX.XX”. If they did it the troubleshoot process would be more quick.

To solve the problem we installed Oracle client and the issue was gone.

Based on this issue I recommend the following:

  1. Be totally sure about the real cause of the problem before throwing an exception;
  2. Don’t masquerade the real problem;
  3. If you really want masquerade the problem use the InnerException property. This helps a lot;

Hope it helped you!

-George

My First Post!

June 5th, 2008

Hi and welcome to my blog!

My name is George and I work as IT advisor. I created this blog to share experiences with others and to document my findings so I can find them again easily. ;)

Here you will find technical posts about Windows in general (I know that this blog has the word Development in its name, but I will blog about Windows in general). I´m a Microsoft guy, I breath Microsoft technology everyday and to me their products are awesome!

Here is a brief list of subjects that you will see here:

  1. General topics about Windows troubleshooting and debugging;
  2. Managed and native development on Windows using C, C++ and C# languages;
  3. Active Directory;
  4. SQL Server;
  5. Network Analysis;
  6. Tools;
  7. High Performance Computing;

If you have any question, suggestion, etc please e-mail me at george@windevblog.com and I promiss that I will reply as soon as possible.

Thanks and enjoy my blog!

-George