Tuesday, April 20, 2010

Visual studio 2010 Premium from MSDN subscription

Following components installs as part of this on windows 7 x64 box. It is pre-pidded, so no key needs to be entered. I used WinRAR to extract ISO file in one folder.



Previous installation of Beta version though left two components on machine.


Strangely on one machine in office where Beta was installed earlier, reboot was required fairly early in setup process. This home machine which had RC earlier is not asking for reboot though.

Saturday, April 3, 2010

How does a C program work

Being a new user in stack overflow, I cannot post more than one link, hence ended up writing answer here. Question is Some general C questions.

It seemed intriguing, so I did some research and then found few things, which are explained below.

MSDN has some material on C language. Check out [C langugae reference on MSDN][1] . In general, in my view, when you are programming on Windows, it is good to search MSDN using Google. You will find many useful samples of OS APIs along the way making your job much easier. The new MSDN layout of related links of left side of a help page can also help discover things.

Now, as for the structure of program and how it executes. When compiling, your compiler will look into standard location for standard c library calls. When using Visual studio on Windows, those functions will be found inside msvcrtxxx.dll. On VS 2010, XXX is 100 or version 10. In VS 2010, you can tell it to use VC90 also. More is [here][2] and @ [Run time library reference][3]. This DLL will not be linked inside your program. Only a reference or stub will be inserted inside using the corresponding .lib file. At runtime, the DLL that actually implemented this function will be loaded into memory and stub will be extended to the address of function in DLL. This DLL is part of your program's virtual memory. BTW, A DLL is like shared library of UNIX. Once loaded into memory, other programs too can reference its functions. You can used [depends.exe][4] to see the implicit dependency of your program. In windows, you can use loadlibrary to explicitly load dll at runtime also and then use its functions.

For non-standard C functions or OS APIs, you will need to see help to find the library name that implemented it. So, if you need to get system information, [GetSystemInfo][5] will need to be called. Seeing its help on MSDN, you notice that it asks you to use kernel32.dll/kernel32.lib. During compilation, you will refer to kernel32.lib using a compiler (cl.exe for VS) switch and during runtime, kernel32.dll will be located by VC runtime as this is standard OS library. Runtime mostly does this de-referencing only once for each function call. You can use Cl.exe switches to specify the custom location of dll & lib files also.

For non-standard C functions and non-standard OS APIs, you will need to see their help to find the library name that implemented it and put/locate that DLL on system running the application. Usually, setup project of VS does all this and put things in nice package for you to deploy on target machine.

You can choose to do static binding of libraries also. This saves times in loading DLLs as well as runtime de-referencing, but increase program size since library code is embedded inside your exe. 

For EXE structure, check out [Peering inside the PE][6] and [Portable Executable structure][7]. All windows EXE are structured in this way or a slight variant. For your executable created by C program, exact entry point will not be main() function. Compiler creates another functions known as initialization and termination functions inside your executable. See [GNU CC Init/Terminate][8] & [Sun Init/Terminate][9]. As you continue working on C programs, you will get to know these things better. In short, Init functions do stack & static data space setup, required dll loading and in general setting up environment. They also process arguments received. After all this is done, main is called with arguments. Once main exits, again terminate routines are called which handles passing back return values, closing open handles & general cleanup. Implementation is very much compiler and OS dependent.

  [1]: http://msdn.microsoft.com/en-us/library/fw5abdx6(v=VS.80).aspx
  [2]: http://msdn.microsoft.com/en-us/library/abx4dbyh(VS.80).aspx
  [3]: http://msdn.microsoft.com/en-us/library/59ey50w6(v=VS.80).aspx
  [4]: http://www.dependencywalker.com/
  [5]: http://msdn.microsoft.com/en-us/library/ms724381(VS.85).aspx
  [6]: http://msdn.microsoft.com/en-us/library/ms809762.aspx
  [7]: http://www.skynet.ie/~caolan/publink/winresdump/winresdump/doc/pefile.html
  [8]: http://gcc.gnu.org/onlinedocs/gccint/Initialization.html
  [9]: http://docs.sun.com/app/docs/doc/817-3677/6mj8mbtbi?a=view

PS: Even though Stack overflow did not allow me to post this thing on their site, I like their editor which creates a nice structure. I will consider writing my entries on their site in future and then copy-paste in windows live writer for better alignment and further posting.

Toughest thing to search was Initialization and termination routines reference. Definitely, their is a lack of a standard documentation on windows platform for internals of tools used by us.

Friday, April 2, 2010

Powershell: Play with Media files

Code Snippet
  1. function MediaObjects($FolderName=".")
  2. {
  3.     #http://huddledmasses.org/editing-media-tags-from-powershell/
  4.     #http://developer.novell.com/wiki/index.php/TagLib_Sharp
  5.     if (![AppDomain]::CurrentDomain.GetAssemblies() | ?{$_.fullname -like "taglib-sharp*"}){
  6.         Write-Host $("taglib-sharp is not loaded. use below command to load it");
  7.         Write-Host $("[Reflection.Assembly]::LoadFrom( (Resolve-Path <Path of \taglib-sharp.dll>) )");
  8.         return (@())
  9.     }
  10.     if (![System.IO.Directory]::Exists($FolderName)){
  11.         Write-Host $($FolderName + " : Media directory does not exist.");
  12.         return (@())
  13.     }
  14.     $mediaExtensionList = @(".asf",".avi",".flac",".m4a",".m4p",".m4v", `
  15.               ".mp+",".mp3",".mp4",".mpc",".mpe",".mpeg",".mpg", `
  16.               ".mpp",".mpv2",".ogg",".wav",".wma",".wmv",".wv")
  18.     $FileList = dir -Recurse -Include "*.*" -Path $FolderName |  `
  19.             ?{($_ -is [IO.FileSystemInfo]) -and ($mediaExtensionList -contains $_.Extension)}
  20.     if (!$FileList){
  21.         return (@())
  22.     }else{
  23.         $ObjList=@()
  24.         foreach ($Item in $FileList)
  25.         {
  26.             #http://huddledmasses.org/trap-exception-in-powershell/
  27.             #Excellent article
  28.             trap [Exception]{
  29.                 Write-Host $($Item.FullName + " threw exception.");
  30.                 write-host $("`tTRAPPED: " + $_.Exception.GetType().FullName);
  31.                  write-host $("`tTRAPPED: " + $_.Exception.Message);
  32.                 continue
  33.             }
  34.             $ObjList += [TagLib.File]::Create($Item.FullName)
  35.         }
  36.         return ($ObjList)
  37.     }
  38. }
  40. function modifyMediaFiles($FolderName=".", $TagName="Genres", $NewTagValue="Hindi Movie")
  41. {
  42.     Write-Host $("Only display the name of those which are getting modified");
  43.     foreach ($media in @(MediaObjects($FolderName)))
  44.     {
  45.         if (($media.tag.$TagName -contains $NewTagValue) `
  46.          -and ($media.tag.$TagName.length -eq 1 ) )
  47.         {
  48.             continue;
  49.         }
  50.         $media.tag.$TagName=@($NewTagValue)
  51.         $media.save()
  52.         $media.name
  53.     }
  54. }
  56. function showMediaTags($FolderName=".", $TagName="Genres")
  57. {
  58.     foreach ($media in @(MediaObjects($FolderName)))
  59.     {
  60.         Write-Host $(([String]::Join(";=;",$media.tag.$TagName)+" : "+$media.Name));
  61.     }
  62. }
  64. #showMediaTags
  65. #modifyMediaFiles "G:\Music\HindiMovies\2005"
  66. #modifyMediaFiles "G:\Music\HindiMovies\2006"
  67. #showMediaTags "G:\Music\HindiMovies\2006"
  68. #showMediaTags "G:\Music\HindiMovies\2009\Aagey Se Right"
Some attribution first

Original Explanation: http://huddledmasses.org/editing-media-tags-from-powershell/

Media Toolset: http://developer.novell.com/wiki/index.php/TagLib_Sharp Nice one to work with media files

How to handle exception: http://huddledmasses.org/trap-exception-in-powershell/

Good discussion on how to return arrays: http://blogs.msdn.com/powershell/archive/2007/01/23/array-literals-in-powershell.aspx

Power GUI: http://powergui.org/index.jspa . A nice tool.

It took some iterations, but final thing came pretty easy. MediaObjects as shown below can be saved in our profile script. At the same time, we can add loading of taglib-sharp also in profile folder. Anyway, function will warn you if not loaded. showMediaTags & modifyMediaFiles are two examples, but we can use many more such small function once we get System.Array of TagLib.Mpeg.AudioFile from MediaObjects.

Notice how I am returning empty array and how exception is handled. Above links have more explanation on each of these.

Using the functions, I could make modification in lot of files.

Code highlighter plugin in windows live writer