RoboNight 2011 - Erster Platz für die RoboGuards

Auch dieses Jahr haben wir wieder an der RoboNight teilgenommen, welche einmal jährlich von der Saarbrücker HTW (Hochschule für Technik und Wirtschaft) gemeinsam mit der Telekom-Tochter T-Systems veranstaltet wird. Bereits vorletztes und letztes Jahr nahmen wir an dem saarländischen Robotik-Wettbewerb teil, 2009 errichten wir den dritten Platz, letztes Jahr den zweiten. Gestern haben wir den ersten Preis gewonnen.

Bereits um 9.00 Uhr begann die RoboNight, nach einer Einführung in die Aufgaben und Regeln, konnten wir gegen 10.00 Uhr anfangen die LEGO Mindstorms NXT-Roboter zusammenzubauen und zu programmieren. Um 16:30 sollte Abgabeschluss sein, dieser wurde jedoch "völlig überraschend" um 20 Minuten verlängert. Wie jedes Jahr gab es drei Aufgaben, die zu bewältigen waren:

Die erste Aufgabe bestand darin, eine Zahlenfolge über Bluetooth zu empfangen und je nach Kombination entsprechende Schalter anzufahren. Bei optimaler Lösung waren 50 Punkte zu erreichen, wir haben nur 30 erreicht, da sich unser Roboter mit einem Zahnrad verfing und den letzten Schalter nicht betätigte. Auch die Zeit wurde bewertet. Der schnellste Roboter Roboter hat zehn Punkte bekommen, der zweite neun und so weiter, immer absteigend.

In der zweiten Aufgabe ging es um ein Umspannwerk, in dem man Hindernisse von einer Linie räumen und wieder darauf ablegen musste. Allerdings durfte dabei das angrenzende Hochspannungsfeld nicht vom Roboter befahren werden. Auch hier wurde die Zeit genau wie bei der ersten Aufgabe bewertet. Unser Roboter war ziemlich schnell und wir waren die Einzigen, die die Aufgabe vollständig lösen konnten und haben 50 oder 49 Punkte erreicht.

"Netzaufbau" war der Name der letzten Herausforderung, man musste an einer Linie entlangfahren und dreimal jeweils zur Rechten drei "Strommasten" (an Scharnieren befestigte, kleine Bretter mit Schnappmechanismus) aufstellen. Am Ende der Linie musste man einen Schalter betätigen, um eine Glühbirne (Symbol für das Land der Ideen) zum Leuchten zu bringen. Zu unserem Schrecken schlug unser erster Versuch fehl, jedoch klappte es beim zweiten Mal einwandfrei. Wie auch bei den anderen Aufgaben wurde auch hier die Zeit mit in die Bewertung einbezogen. Wir haben bei dieser Aufgabe 50 Punkte plus unsere Zeitpunkte erhalten.

Am Ende fand die die Preisverleihung mehr oder weniger spannend statt, denn bereits vor der Verleihung haben uns einige Leute zum bevorstehenden Sieg gratuliert, obwohl ich mir da doch noch nicht allzu sicher sein wollte. Knapp hinter uns auf dem zweiten Platz landeten "Die Relativen", ein Team vom Albert-Einstein-Gymnasium in Völklingen.

Genauere Informationen befinden sich in der HTW-Online-Ausgabe Nr. 87 unter https://www.htw-saarland.de/organisation/htwonline/2011/87/9-t-systems-htw-robonight-in-saarbrucken-roboter-im-bereich-erneuerbarer-energien

Download YouTube Videos using any programming language

Dear reader,

in this article I will show you how to write an application for downloading videos from the online platform YouTube using any programming language like C# .Net, JavaScript or any other language. I think this topic is quite interesting because I implemented a download function in my YouTube Gadget and I did not find any helpful resources on the internet.

Let's imagine following situation: You found

a cool video on YouTube, now you want to download it (for playing it on your PC, mobile phone or iPod...).
What we do have is the URL of the YouTube interface similar to "http://www.youtube.com/watch?v=M1wbceaOwfg" containing the swf-file that plays our video.
What we do not have is the URL of the video file our browser is loading. I used Firebug, a useful extension for developers, to get the video file.

Firebug - Getting the video URL

As you can see, I activated the "Netzwerk/Network" module and selected "Flash" contents. You notice that the request which is shown is the request for the video because of the "Content-Type" field of the response header ("Antwort-Header") which is set to "video/x-flv", the mimetype of flv-flash-videos. If you copy the requested URL to the address bar of our browser,  a download dialog will be shown and ask you to open or save "videoplayback". Well, if this file is opened with Adobe Media Player or any other program being able to play flv-videos, you will see that you can watch the downloaded video.

I think this is clear, but more interesting is to automate this process and to download/convert the videos to a more common format. Which mobile phone or iPod can play flv-files? So the next step to do is to search the source code of the YouTube video page for our urls. And - to put it in a nutshell - it can be found in the flashvars of the embed-tag or the object (using Firefox, YouTube's sourcecode is using an embed-tag while YouTube's sourcecode for Internet Explorer is using an object-tag).
And this is the quite long code my sourcecode contains:

<embed type="application/x-shockwave-flash"     src="http://s.ytimg.com/yt/swfbin/watch_as3-vfl3Eh29q.swf"     width="640" id="movie_player" height="390"    flashvars="fexp=903104%2C907702&amp;url_encoded_fmt_stream_map=url%3Dhttp%253A%252F%252Fo-o.preferred.fra02s03.v11.lscache4.c.youtube.com%252Fvideoplayback%253Fsparams%253Did%25252Cexpire%25252Cip%25252Cipbits%25252Citag%25252Cratebypass%25252Ccp%2526fexp%253D903104%25252C907702%2526itag%253D43%2526ip%253D87.0.0.0%2526signature%253D30417352A65E14163FB6746AE6C6A871517A5FC9.0C91E36B690A5C885AAE0B7F43FE564444C00AD0%2526sver%253D3%2526ratebypass%253Dyes%2526expire%253D1317600000%2526key%253Dyt1%2526ipbits%253D8%2526cp%253DU0hQTFZLTl9FSkNOMF9ORVJBOms0SXNQbnhxVEI4%2526id%253D335c1b71e68ec1f8%26quality%3Dmedium%26fallback_host%3Dtc.v11.cache4.c.youtube.com%26type%3Dvideo%252Fwebm%253B%2Bcodecs%253D%2522vp8.0%252C%2Bvorbis%2522%26itag%3D43%2Curl%3Dhttp%253A%252F%252Fo-o.preferred.fra02s03.v21.lscache2.c.youtube.com%252Fvideoplayback%253Fsparams%253Did%25252Cexpire%25252Cip%25252Cipbits%25252Citag%25252Calgorithm%25252Cburst%25252Cfactor%25252Ccp%2526fexp%253D903104%25252C907702%2526algorithm%253Dthrottle-factor%2526itag%253D34%2526ip%253D87.0.0.0%2526burst%253D40%2526sver%253D3%2526signature%253DBC4BD5E7A48929985F533325AE046E5812B24D45.E599953DFB49361BD0CCDAE3A1FD06C4C7ED5A%2526expire%253D1317600000%2526key%253Dyt1%2526ipbits%253D8%2526factor%253D1.25%2526cp%253DU0hQTFZLTl9FSkNOMF9ORVJBOms0SXNQbnhxVEI4%2526id%253D335c1b71e68ec1f8%26quality%3Dmedium%26fallback_host%3Dtc.v21.cache2.c.youtube.com%26type%3Dvideo%252Fx-flv%26itag%3D34%2Curl%3Dhttp%253A%252F%252Fo-o.preferred.fra02s03.v22.lscache3.c.youtube.com%252Fvideoplayback%253Fsparams%253Did%25252Cexpire%25252Cip%25252Cipbits%25252Citag%25252Cratebypass%25252Ccp%2526fexp%253D903104%25252C907702%2526itag%253D18%2526ip%253D87.0.0.0%2526signature%253D81FDB64A4A19D55942C6C05CE4752A209C75C00D.D45F795019B8E8214EA20037660EF2B534C817F7%2526sver%253D3%2526ratebypass%253Dyes%2526expire%253D1317600000%2526key%253Dyt1%2526ipbits%253D8%2526cp%253DU0hQTFZLTl9FSkNOMF9ORVJBOms0SXNQbnhxVEI4%2526id%253D335c1b71e68ec1f8%26quality%3Dmedium%26fallback_host%3Dtc.v22.cache3.c.youtube.com%26type%3Dvideo%252Fmp4%253B%2Bcodecs%253D%2522avc1.42001E%252C%2Bmp4a.40.2%2522%26itag%3D18%2Curl%3Dhttp%253A%252F%252Fo-o.preferred.fra02s03.v22.lscache3.c.youtube.com%252Fvideoplayback%253Fsparams%253Did%25252Cexpire%25252Cip%25252Cipbits%25252Citag%25252Calgorithm%25252Cburst%25252Cfactor%25252Ccp%2526fexp%253D903104%25252C907702%2526algorithm%253Dthrottle-factor%2526itag%253D5%2526ip%253D87.0.0.0%2526burst%253D40%2526sver%253D3%2526signature%253DAB1BAAB6AEB36AA5449436B3B70DAEAC6CF4A309.BFF1F8A5C9179CF25B9121968EA70A0A31DE0088%2526expire%253D1317600000%2526key%253Dyt1%2526ipbits%253D8%2526factor%253D1.25%2526cp%253DU0hQTFZLTl9FSkNOMF9ORVJBOms0SXNQbnhxVEI4%2526id%253D335c1b71e68ec1f8%26quality%3Dsmall%26fallback_host%3Dtc.v22.cache3.c.youtube.com%26type%3Dvideo%252Fx-flv%26itag%3D5&amp;enablecsi=1&amp;watermark=http%3A%2F%2Fs.ytimg.com%2Fyt%2Fswf%2Flogo-vfl_bP6ud.swf%2Chttp%3A%2F%2Fs.ytimg.com%2Fyt%2Fswf%2Fhdlogo-vfloR6wva.swf&amp;timestamp=1317576346&amp;plid=AASuVCYX1Hr0FlbH&amp;allow_embed=1&amp;watch_ajax_token=CzZGESebg7W8TR9XdtjYvm5lj4J8MTMxNzY2Mjc0NkAxMzE3NTc2MzQ2&amp;vq=auto&amp;showpopout=1&amp;autohide=2&amp;hl=en_US&amp;csi_page_type=watch5&amp;keywords=music%2Cyoutube%2Cgadget%2Cprogram%2Capp%2Capplication%2Csoftware%2Cwindows%2Cvista%2Cplayer%2Cplaylists%2Clisten%2Csidebar%2Cdesktop%2Cwidgets%2Centertainment%2Ccomputer&amp;cr=DE&amp;rvs=view_count%3D407%26author%3DRoboFan1406%26length_seconds%3D%2528104%252C%2529%26id%3D8q9RJ1wZQ5E%26title%3DLord%2Bof%2Bthe%2BRings%2B-%2BLord%2Bof%2Bthe%2BRings%2B-%2BShire%2BMusic%2Cview_count%3D162%26author%3DRoboFan1406%26length_seconds%3D%2528168%252C%2529%26id%3DyXnxYgUA2IA%26title%3DClimbing%2BNXT%2Cview_count%3D288%26author%3DRoboFan1406%26length_seconds%3D%2528109%252C%2529%26id%3DTRtIuqiBh50%26title%3DLEGO%2BMindstorms%2BNXT%2BGabelstapler%2Cview_count%3D4318143%26author%3DElektraRecords%26length_seconds%3D%2528257%252C%2529%26id%3Dfwr1hm_oBxE%26title%3DBruno%2BMars%2B-%2BIt%2BWill%2BRain%2B%255BNew%2BMusic%255D%2Cview_count%3D2724048%26author%3DkellyclarksonVEVO%26length_seconds%3D%2528235%252C%2529%26id%3D0C_oNMH0GTk%26title%3DKelly%2BClarkson%2B-%2BMr.%2BKnow%2BIt%2BAll%2Cview_count%3D2980984%26author%3DSMTOWN%26length_seconds%3D%2528203%252C%2529%26id%3DGvTaLTTanJc%26title%3DSuper%2BJunior%2B%25EC%258A%2588%25ED%258D%25BC%25EC%25A3%25BC%25EB%258B%2588%25EC%2596%25B4_A-CHA_Music%2BVideo%2Cview_count%3D1815682%26author%3DYourfavoritemartian%26length_seconds%3D%2528209%252C%2529%26id%3DTUmJDVRDRTQ%26title%3DWHIP%2BYO%2BKIDS%2Bfeaturing%2BNice%2BPeter%2Cview_count%3D953666%26author%3Drecklessswaggg%26length_seconds%3D%2528241%252C%2529%26id%3DPQocCi6j_mk%26title%3DHOW%2BTO%2BLOVE%2B%2528REMIX%2529%2B-%2BJUSTIN%2BBIEBER&amp;endscreen_module=http%3A%2F%2Fs.ytimg.com%2Fyt%2Fswfbin%2Fendscreen-vflNhEga_.swf&amp;fmt_list=43%2F320x240%2F99%2F0%2F0%2C34%2F320x240%2F9%2F0%2F115%2C18%2F320x240%2F9%2F0%2F115%2C5%2F320x240%2F7%2F0%2F0&amp;referrer=None&amp;user_gender=m&amp;logwatch=1&amp;length_seconds=25&amp;sendtmp=1&amp;enablejsapi=1&amp;sk=764YjHpjrC6O1ctvYaH35ppV7Bd9b6mnR&amp;theme=dark&amp;t=vjVQa1PpcFM-sb-PCui5mX1jKwIXdE1yWObSxWPQFp8%3D&amp;video_id=M1wbceaOwfg&amp;p_w=P-KpDhgwPVs&amp;tk=SVN8E4f4bLdCNRlCrLgJIJlnzby7tCDb5dJjT08JFAX6-DLCnnC5rQ%3D%3D&amp;user_age=33"     allowscriptaccess="always" allowfullscreen="true" bgcolor="#000000">

To make our flashvars more readable and accessible I decrypted the html-entities: (The following only shows the decoded flash parameters/flashvars, the other code is not too interesting.)

fexp=903104%2C907702
&url_encoded_fmt_stream_map=url%3Dhttp%253A%252F%252Fo-o.preferred.fra02s03.v11.lscache4.c.youtube.com%252Fvideoplayback%253Fsparams%253Did%25252Cexpire%25252Cip%25252Cipbits%25252Citag%25252Cratebypass%25252Ccp%2526fexp%253D903104%25252C907702%2526itag%253D43%2526ip%253D87.0.0.0%2526signature%253D30417352A65E14163FB6746AE6C6A871517A5FC9.0C91E36B690A5C885AAE0B7F43FE564444C00AD0%2526sver%253D3%2526ratebypass%253Dyes%2526expire%253D1317600000%2526key%253Dyt1%2526ipbits%253D8%2526cp%253DU0hQTFZLTl9FSkNOMF9ORVJBOms0SXNQbnhxVEI4%2526id%253D335c1b71e68ec1f8%26quality%3Dmedium%26fallback_host%3Dtc.v11.cache4.c.youtube.com%26type%3Dvideo%252Fwebm%253B%2Bcodecs%253D%2522vp8.0%252C%2Bvorbis%2522%26itag%3D43%2Curl%3Dhttp%253A%252F%252Fo-o.preferred.fra02s03.v21.lscache2.c.youtube.com%252Fvideoplayback%253Fsparams%253Did%25252Cexpire%25252Cip%25252Cipbits%25252Citag%25252Calgorithm%25252Cburst%25252Cfactor%25252Ccp%2526fexp%253D903104%25252C907702%2526algorithm%253Dthrottle-factor%2526itag%253D34%2526ip%253D87.0.0.0%2526burst%253D40%2526sver%253D3%2526signature%253DBC4BD5E7A48929985F533325AE046E5812B24D45.E599953DFB49361BD0CCDAE3A1FD06C4C7ED5A%2526expire%253D1317600000%2526key%253Dyt1%2526ipbits%253D8%2526factor%253D1.25%2526cp%253DU0hQTFZLTl9FSkNOMF9ORVJBOms0SXNQbnhxVEI4%2526id%253D335c1b71e68ec1f8%26quality%3Dmedium%26fallback_host%3Dtc.v21.cache2.c.youtube.com%26type%3Dvideo%252Fx-flv%26itag%3D34%2Curl%3Dhttp%253A%252F%252Fo-o.preferred.fra02s03.v22.lscache3.c.youtube.com%252Fvideoplayback%253Fsparams%253Did%25252Cexpire%25252Cip%25252Cipbits%25252Citag%25252Cratebypass%25252Ccp%2526fexp%253D903104%25252C907702%2526itag%253D18%2526ip%253D87.0.0.0%2526signature%253D81FDB64A4A19D55942C6C05CE4752A209C75C00D.D45F795019B8E8214EA20037660EF2B534C817F7%2526sver%253D3%2526ratebypass%253Dyes%2526expire%253D1317600000%2526key%253Dyt1%2526ipbits%253D8%2526cp%253DU0hQTFZLTl9FSkNOMF9ORVJBOms0SXNQbnhxVEI4%2526id%253D335c1b71e68ec1f8%26quality%3Dmedium%26fallback_host%3Dtc.v22.cache3.c.youtube.com%26type%3Dvideo%252Fmp4%253B%2Bcodecs%253D%2522avc1.42001E%252C%2Bmp4a.40.2%2522%26itag%3D18%2Curl%3Dhttp%253A%252F%252Fo-o.preferred.fra02s03.v22.lscache3.c.youtube.com%252Fvideoplayback%253Fsparams%253Did%25252Cexpire%25252Cip%25252Cipbits%25252Citag%25252Calgorithm%25252Cburst%25252Cfactor%25252Ccp%2526fexp%253D903104%25252C907702%2526algorithm%253Dthrottle-factor%2526itag%253D5%2526ip%253D87.0.0.0%2526burst%253D40%2526sver%253D3%2526signature%253DAB1BAAB6AEB36AA5449436B3B70DAEAC6CF4A309.BFF1F8A5C9179CF25B9121968EA70A0A31DE0088%2526expire%253D1317600000%2526key%253Dyt1%2526ipbits%253D8%2526factor%253D1.25%2526cp%253DU0hQTFZLTl9FSkNOMF9ORVJBOms0SXNQbnhxVEI4%2526id%253D335c1b71e68ec1f8%26quality%3Dsmall%26fallback_host%3Dtc.v22.cache3.c.youtube.com%26type%3Dvideo%252Fx-flv%26itag%3D5
&enablecsi=1
&watermark=http%3A%2F%2Fs.ytimg.com%2Fyt%2Fswf%2Flogo-vfl_bP6ud.swf%2Chttp%3A%2F%2Fs.ytimg.com%2Fyt%2Fswf%2Fhdlogo-vfloR6wva.swf
&timestamp=1317576346
&plid=AASuVCYX1Hr0FlbH
&allow_embed=1
&watch_ajax_token=CzZGESebg7W8TR9XdtjYvm5lj4J8MTMxNzY2Mjc0NkAxMzE3NTc2MzQ2
&vq=auto
&showpopout=1
&autohide=2
&hl=en_US
&csi_page_type=watch5
&keywords=music%2Cyoutube%2Cgadget%2Cprogram%2Capp%2Capplication%2Csoftware%2Cwindows%2Cvista%2Cplayer%2Cplaylists%2Clisten%2Csidebar%2Cdesktop%2Cwidgets%2Centertainment%2Ccomputer
&cr=DE
&rvs=view_count%3D407%26author%3DRoboFan1406%26length_seconds%3D%2528104%252C%2529%26id%3D8q9RJ1wZQ5E%26title%3DLord%2Bof%2Bthe%2BRings%2B-%2BLord%2Bof%2Bthe%2BRings%2B-%2BShire%2BMusic%2Cview_count%3D162%26author%3DRoboFan1406%26length_seconds%3D%2528168%252C%2529%26id%3DyXnxYgUA2IA%26title%3DClimbing%2BNXT%2Cview_count%3D288%26author%3DRoboFan1406%26length_seconds%3D%2528109%252C%2529%26id%3DTRtIuqiBh50%26title%3DLEGO%2BMindstorms%2BNXT%2BGabelstapler%2Cview_count%3D4318143%26author%3DElektraRecords%26length_seconds%3D%2528257%252C%2529%26id%3Dfwr1hm_oBxE%26title%3DBruno%2BMars%2B-%2BIt%2BWill%2BRain%2B%255BNew%2BMusic%255D%2Cview_count%3D2724048%26author%3DkellyclarksonVEVO%26length_seconds%3D%2528235%252C%2529%26id%3D0C_oNMH0GTk%26title%3DKelly%2BClarkson%2B-%2BMr.%2BKnow%2BIt%2BAll%2Cview_count%3D2980984%26author%3DSMTOWN%26length_seconds%3D%2528203%252C%2529%26id%3DGvTaLTTanJc%26title%3DSuper%2BJunior%2B%25EC%258A%2588%25ED%258D%25BC%25EC%25A3%25BC%25EB%258B%2588%25EC%2596%25B4_A-CHA_Music%2BVideo%2Cview_count%3D1815682%26author%3DYourfavoritemartian%26length_seconds%3D%2528209%252C%2529%26id%3DTUmJDVRDRTQ%26title%3DWHIP%2BYO%2BKIDS%2Bfeaturing%2BNice%2BPeter%2Cview_count%3D953666%26author%3Drecklessswaggg%26length_seconds%3D%2528241%252C%2529%26id%3DPQocCi6j_mk%26title%3DHOW%2BTO%2BLOVE%2B%2528REMIX%2529%2B-%2BJUSTIN%2BBIEBER
&endscreen_module=http%3A%2F%2Fs.ytimg.com%2Fyt%2Fswfbin%2Fendscreen-vflNhEga_.swf
&fmt_list=43%2F320x240%2F99%2F0%2F0%2C34%2F320x240%2F9%2F0%2F115%2C18%2F320x240%2F9%2F0%2F115%2C5%2F320x240%2F7%2F0%2F0
&referrer=None
&user_gender=m
&logwatch=1
&length_seconds=25
&sendtmp=1
&enablejsapi=1
&sk=764YjHpjrC6O1ctvYaH35ppV7Bd9b6mnR
&theme=dark
&t=vjVQa1PpcFM-sb-PCui5mX1jKwIXdE1yWObSxWPQFp8%3D
&video_id=M1wbceaOwfg
&p_w=P-KpDhgwPVs
&tk=SVN8E4f4bLdCNRlCrLgJIJlnzby7tCDb5dJjT08JFAX6-DLCnnC5rQ%3D%3D
&user_age=20

The information sent to the Shockwave flash video is pretty interesting. My gender and age... For us, the interesting parameter is "url_encoded_fmt_stream_map". This parameter is URL-encoded, here it it decoded.

url=http%3A%2F%2Fo-o.preferred.fra02s03.v11.lscache4.c.youtube.com%2Fvideoplayback%3Fsparams%3Did%252Cexpire%252Cip%252Cipbits%252Citag%252Cratebypass%252Ccp%26fexp%3D903104%252C907702%26itag%3D43%26ip%3D87.0.0.0%26signature%3D30417352A65E14163FB6746AE6C6A871517A5FC9.0C91E36B690A5C885AAE0B7F43FE564444C00AD0%26sver%3D3%26ratebypass%3Dyes%26expire%3D1317600000%26key%3Dyt1%26ipbits%3D8%26cp%3DU0hQTFZLTl9FSkNOMF9ORVJBOms0SXNQbnhxVEI4%26id%3D335c1b71e68ec1f8&quality=medium&fallback_host=tc.v11.cache4.c.youtube.com&type=video%2Fwebm%3B+codecs%3D%22vp8.0%2C+vorbis%22&itag=43
,url=http%3A%2F%2Fo-o.preferred.fra02s03.v21.lscache2.c.youtube.com%2Fvideoplayback%3Fsparams%3Did%252Cexpire%252Cip%252Cipbits%252Citag%252Calgorithm%252Cburst%252Cfactor%252Ccp%26fexp%3D903104%252C907702%26algorithm%3Dthrottle-factor%26itag%3D34%26ip%3D87.0.0.0%26burst%3D40%26sver%3D3%26signature%3DBC4BD5E7A48929985F533325AE046E5812B24D45.E599953DFB49361BD0CCDAE3A1FD06C4C7ED5A%26expire%3D1317600000%26key%3Dyt1%26ipbits%3D8%26factor%3D1.25%26cp%3DU0hQTFZLTl9FSkNOMF9ORVJBOms0SXNQbnhxVEI4%26id%3D335c1b71e68ec1f8&quality=medium&fallback_host=tc.v21.cache2.c.youtube.com&type=video%2Fx-flv&itag=34
,url=http%3A%2F%2Fo-o.preferred.fra02s03.v22.lscache3.c.youtube.com%2Fvideoplayback%3Fsparams%3Did%252Cexpire%252Cip%252Cipbits%252Citag%252Cratebypass%252Ccp%26fexp%3D903104%252C907702%26itag%3D18%26ip%3D87.0.0.0%26signature%3D81FDB64A4A19D55942C6C05CE4752A209C75C00D.D45F795019B8E8214EA20037660EF2B534C817F7%26sver%3D3%26ratebypass%3Dyes%26expire%3D1317600000%26key%3Dyt1%26ipbits%3D8%26cp%3DU0hQTFZLTl9FSkNOMF9ORVJBOms0SXNQbnhxVEI4%26id%3D335c1b71e68ec1f8&quality=medium&fallback_host=tc.v22.cache3.c.youtube.com&type=video%2Fmp4%3B+codecs%3D%22avc1.42001E%2C+mp4a.40.2%22&itag=18
,url=http%3A%2F%2Fo-o.preferred.fra02s03.v22.lscache3.c.youtube.com%2Fvideoplayback%3Fsparams%3Did%252Cexpire%252Cip%252Cipbits%252Citag%252Calgorithm%252Cburst%252Cfactor%252Ccp%26fexp%3D903104%252C907702%26algorithm%3Dthrottle-factor%26itag%3D5%26ip%3D87.0.0.0%26burst%3D40%26sver%3D3%26signature%3DAB1BAAB6AEB36AA5449436B3B70DAEAC6CF4A309.BFF1F8A5C9179CF25B9121968EA70A0A31DE0088%26expire%3D1317600000%26key%3Dyt1%26ipbits%3D8%26factor%3D1.25%26cp%3DU0hQTFZLTl9FSkNOMF9ORVJBOms0SXNQbnhxVEI4%26id%3D335c1b71e68ec1f8&quality=small&fallback_host=tc.v22.cache3.c.youtube.com&type=video%2Fx-flv&itag=5

Conspicious is that the parameter is not completely decoded, but the rest is very readable. All related parameter collections are separated by a comma, their parameters with values are separated by an "&"-character but the values are URL-encoded again - here is the completely decoded version:

url=http://o-o.preferred.fra02s03.v11.lscache4.c.youtube.com/videoplayback?sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Cratebypass%2Ccp
&fexp=903104%2C907702
&itag=43
&ip=87.0.0.0
&signature=30417352A65E14163FB6746AE6C6A871517A5FC9.0C91E36B690A5C885AAE0B7F43FE564444C00AD0
&sver=3
&ratebypass=yes
&expire=1317600000
&key=yt1
&ipbits=8
&cp=U0hQTFZLTl9FSkNOMF9ORVJBOms0SXNQbnhxVEI4
&id=335c1b71e68ec1f8
&quality=medium
&fallback_host=tc.v11.cache4.c.youtube.com
&type=video/webm;+codecs="vp8.0,+vorbis"
&itag=43

,url=http://o-o.preferred.fra02s03.v21.lscache2.c.youtube.com/videoplayback?sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Calgorithm%2Cburst%2Cfactor%2Ccp
&fexp=903104%2C907702
&algorithm=throttle-factor
&itag=34
&ip=87.0.0.0
&burst=40
&sver=3
&signature=BC4BD5E7A48929985F533325AE046E5812B24D45.E599953DFB49361BD0CCDAE3A1FD06C4C7ED5A
&expire=1317600000
&key=yt1
&ipbits=8
&factor=1.25
&cp=U0hQTFZLTl9FSkNOMF9ORVJBOms0SXNQbnhxVEI4
&id=335c1b71e68ec1f8
&quality=medium
&fallback_host=tc.v21.cache2.c.youtube.com
&type=video/x-flv
&itag=34

,url=http://o-o.preferred.fra02s03.v22.lscache3.c.youtube.com/videoplayback?sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Cratebypass%2Ccp
&fexp=903104%2C907702
&itag=18
&ip=87.0.0.0
&signature=81FDB64A4A19D55942C6C05CE4752A209C75C00D.D45F795019B8E8214EA20037660EF2B534C817F7
&sver=3
&ratebypass=yes
&expire=1317600000
&key=yt1
&ipbits=8
&cp=U0hQTFZLTl9FSkNOMF9ORVJBOms0SXNQbnhxVEI4
&id=335c1b71e68ec1f8
&quality=medium
&fallback_host=tc.v22.cache3.c.youtube.com
&type=video/mp4;+codecs="avc1.42001E,+mp4a.40.2"
&itag=18

,url=http://o-o.preferred.fra02s03.v22.lscache3.c.youtube.com/videoplayback?sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Calgorithm%2Cburst%2Cfactor%2Ccp
&fexp=903104%2C907702
&algorithm=throttle-factor
&itag=5
&ip=87.0.0.0
&burst=40
&sver=3
&signature=AB1BAAB6AEB36AA5449436B3B70DAEAC6CF4A309.BFF1F8A5C9179CF25B9121968EA70A0A31DE0088
&expire=1317600000
&key=yt1
&ipbits=8
&factor=1.25
&cp=U0hQTFZLTl9FSkNOMF9ORVJBOms0SXNQbnhxVEI4
&id=335c1b71e68ec1f8
&quality=small
&fallback_host=tc.v22.cache3.c.youtube.com
&type=video/x-flv
&itag=5

Now we have got our data. There are four possible downloads (withdrawable from the type-parameter):

  1. The first download is a WebM video (a video format developed by Google) with a medium quality.
  2. The second download is a flash video with medium quality.
  3. The third download is a mp4-video with medium quality.
  4. The fourth download is a flash video with small quality.

Please note that every whole paragraph displayed in the box above is one single video url, i. e. the download url for the first video type is:

http://o-o.preferred.fra02s03.v11.lscache4.c.youtube.com/videoplayback?sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Cratebypass%2Ccp&fexp=903104%2C907702&itag=43&ip=87.0.0.0&signature=30417352A65E14163FB6746AE6C6A871517A5FC9.0C91E36B690A5C885AAE0B7F43FE564444C00AD0&sver=3&ratebypass=yes&expire=1317600000&key=yt1&ipbits=8&cp=U0hQTFZLTl9FSkNOMF9ORVJBOms0SXNQbnhxVEI4&id=335c1b71e68ec1f8&quality=medium&fallback_host=tc.v11.cache4.c.youtube.com&type=video/webm;+codecs="vp8.0,+vorbis"&itag=43

Now, to download this video, just download the file from this URL and you are done.

Note: It is not possible to demonstrate this function online because we need to send a request to YouTube first to retreive this URL. This is not possible because cross-domain-scripting (XSS) is not allowed by most common browsers.

In my YouTube Gadget I use the following code to download videos:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Video Downloader</title>
</head>
<body>
<h1>AJAX YouTube Video Downloader</h1>
<h2>Demo by <a href="http://robofan.de">robofan.de</a></h2>
<form onsubmit="javascript:DownloadFormats(document.getElementById('VideoURL').value); return false;">
<table cellspacing="3" border="0" cellpadding="0">
<tr><td>Video URL:</td><td><input type="text" id="VideoURL" style="width: 245px;" /></td></tr>
<tr><td>Video format:</td><td><select id="downloadformat" disabled="disabled" style="width: 250px;"><option>Enter the URL of a video first</option></select></td></tr>
<tr><td></td><td><input type="submit" value="Retreive video formats" id="downloadbutton" style="width: 250px;" /></td></tr>
</table>
</form>
<script type="text/javascript">
var Status=0;
function exactTags(text, start, end, number) //this function allows to retreive a string between to tags - example: 'tag("<tag>any text</tag>", "<tag>", "</tag>", 0);' returns "any text"
{
    var first=text.split(start);
    if(first.length > number+1)
    {
        var second=first[number+1];
        first=second.split(end);
        second=first[0];
        return second;
    }
    else
    {
        return "";
    }
}
function DownloadFormats(VideoURL)
{
    if(Status==0)
    {
        var FormatRequest = new ActiveXObject("Microsoft.XMLHTTP");
        FormatRequest.open("GET", VideoURL, true); //initialize request to retreive video URLs
        FormatRequest.onreadystatechange = function()
        {
            if(FormatRequest.readyState === 4)
            {
                if(FormatRequest.status === 200)
                {
                    document.getElementById("downloadformat").disabled=false;
                    document.getElementById("downloadformat").options.length=0;
                    document.getElementById("downloadbutton").value="Download/Show";
                    var DownloadData=decodeURIComponent(exactTags(exactTags(FormatRequest.responseText, '<param name="flashvars" value="', '"', 0), "url_encoded_fmt_stream_map=", "&", 0)).split(",");
                    for(i=0; i < DownloadData.length; i++)
                    {
                        if(decodeURIComponent(exactTags(DownloadData[i], "type=", "&", 0)).split(";")[0]!="video/webm") //If a video is not a Google WebM video
                        {
                            document.getElementById("downloadformat").options[document.getElementById("downloadformat").options.length]=new Option(decodeURIComponent(exactTags(DownloadData[i], "type=", "&", 0)).split(";")[0]+" ("+decodeURIComponent(exactTags(DownloadData[i], "quality=", "&", 0))+")", decodeURIComponent(exactTags(DownloadData[i], "url=", "&", 0))); //Annex the URL to a select-list
                           �
                        }
                    }
                    Status=1;
                }
            }
        }
        FormatRequest.send(null); //Send the request
    }
    else
    {
        window.open(document.getElementById("downloadformat").value);
        Status=0;
        document.getElementById("downloadbutton").value="Retreive video formats";
        document.getElementById("downloadformat").options.length=0;
        document.getElementById("downloadformat").options[0]=new Option("Select a video first");
        document.getElementById("downloadformat").disabled=true;
    }
}
</script>
This is a downloader for YouTube videos. Originally it was programmed for <a href="http://youtube.com">youtube-gadget.com</a>.
<p>Please note that you may - depending on your location - violate laws by downloading videos which are protected by copyright.<br/>The author does not take over responsibility for any kind of abuse of this function or these terms.</p>
</body>
</html>

This works fine for downloading any video except those which are not available in Germany. To use this function in your Internet Explorer (it will not work with other browsers) you can download the document here. (Right click -> Save as...) Please be aware that the document has to be stored in your local file system because otherwise cross domain requests to YouTube are not allowed and it will not work. For the same reason you should allow blocked running scripts or ActiveX controls.

After downloading a video you can several conversion tools to convert the videos to any format.

Thank you for reading this long article, I hope I could inspire you. Please comment.

Best Regards
Birk

Please note that you may - depending on your location - violate laws by downloading videos which are protected by copyright.
The author does not take over responsibility for any kind of abuse of this function or these terms.

Gallery.Live.com offline - Retired because of Windows 8?

My gadgets on gallery.live.com

My gadgets

Yesterday I was very shocked when I saw that Microsoft retired "gallery.live.com". It has always been a suitable platform for submitting my gadgets which got more than 380,000 downloads (the rest of the counted 54,000 downloads came from a similar German Microsoft platform - apps.msn.de - which is luckily not offline - but new contents cannot be submitted either). Another point is that my "Gallery Gadget", which searched for gadgets on the site, does not work anymore, users are now redirected to this page.
The page that is shown instead of the gadget platform shows following message:

The Windows Live Gallery has been retired. In order to focus support on the much richer set of opportunities available for the newest version of Windows, Microsoft is no longer supporting development or uploading of new Gadgets. However, some of the most popular and highest-rated gadgets are still available on the Gadgets page of the Windows Personalization Gallery.

With Windows Developer Preview, developers can create rich app experiences where customers focus on their important tasks. Apps are at the center of the Windows Developer Preview experience and are alive with activity and vibrant content. Users immerse themselves in your full-screen app while Windows gracefully gets out of the way.

Windows Developer Preview allows you to leverage your existing skills and code assets so you can create great experiences for your customers. Gadget and web developers can now use their HTML5 and CSS3 skills to build native Windows apps. .NET Developers can use XAML, C#, and Visual Basic to build beautiful Metro-style apps. Game developers can use the power of DirectX 11.1 to build amazing, immersive gaming experiences. Driver developers benefit from increased productivity with the new, integrated Visual Studio development environment.

(Source: gallery.live.com - October 1, 2011)

Note the third paragraph! Windows Vista and Windows 7 are both still available at the markets and they do not support gadgets anymore while XP is still supported?! Therefore I can now build metro apps for an operating system which has not even reached beta status.
Unfortunately I am not a big fan of the new metro style, I think metro style is more regress than progress. I do not want to use a computer which is not distinguishable from a mobile phone.

UPDATE (January 5, 2012):

If you are searching the gadgets which were available in the gadget gallery, you will find them all at gallery-live.com. Note the difference of the domain name, the new site contains a minus ("-") which replaces the dot (".") in gallery.live.com. This service is operated by myself and not by Microsoft.

"This is not a valid Gadget Package." - Zipping a Windows Sidebar Gadget

Some days ago I got a mail from a user who told me that my new YouTube Gadget could not be installed. This user got the following error: "This is not a valid gadget package." First I thought it was en error because some files were not ready for archiving because the attribute for archiving was missing. I tried to zip the gadget completely but it did not work, neither with WinZip nor with WinRar. I read some topics on the internet but I did not found any solution. So I removed files from the archive step by step until it worked. The last file I removed was an empty file which was preserved for storing settings. So the problem was this empty file. Gadget Packages may not contain empty files or folders. I came to the result that I could create empty folders and files automatically with the file system object (FSO). Here you get some information on the MSDN: http://msdn.microsoft.com/en-us/library/z9ty6h50%28v=vs.85%29.aspx. I hope I could help you.

JavaScript - Htmlentities or htmlspecialchars


Today I wanted to use the htmlentities-function in JavaScript. This useful function is available for PHP but it's not for JavaScript. The reason why I needed the htmlentities-function was the use of the element property innerHTML. I wanted to insert contents into a div container and output some JavaScript variables. The problem: As soon as any user inserts a special character, like ', ", >, < or & and so on, the operation fails of course. First I thought of encoding the variables by the server with an ajax request but I did not want to use up so much traffic. So I came up with this tiny function that works similar to htmlentities but encodes every character, also normal ASCII characters. It does not really encode the characters to html entites but to xml entities which is fine for its use in HTML.
Here is the function:

<script type="text/javascript">
function htmlentities(input)
{
    var code="";
    for(i=0; i < input.length; i++)
    {
        code=code+"&#"+input.charCodeAt(i)+";";
    }
    return code;
}
</script>

If you want to test it, you can do it here:

Input


Raw Output

Output with encoded entities (you will not see any change compared to the input)



This is the code for the code playground above. As you can see it is very simple.

Input
<textarea id="input" rows="3" cols="60">&#115;&#112;&#101;&#99;&#105;&#97;&#108;&#32;&#99;&#104;&#97;&#114;&#97;&#99;&#116;&#101;&#114;&#115;&#58;&#32;&#60;&#62;&#8221;&#38;&#8217;&#32;&#109;&#111;&#114;&#101;&#32;&#115;&#112;&#101;&#99;&#105;&#97;&#108;&#32;&#99;&#104;&#97;&#114;&#97;&#99;&#116;&#101;&#114;&#115;&#58;&#32;&#9835;&#9834;&#32;&#9660;&#9650;&#9660;&#9650;&#32;&#110;&#111;&#114;&#109;&#97;&#108;&#32;&#99;&#104;&#97;&#114;&#97;&#99;&#116;&#101;&#114;&#115;&#58;&#32;&#97;&#98;&#99;&#49;&#50;&#51;</textarea>
<input onclick="javascript:document.getElementById('output').value=htmlentities(document.getElementById('input').value); document.getElementById('enc_output').innerHTML=htmlentities(document.getElementById('input').value);" type="button" value="Run htmlentities()" />
Raw Output
<textarea id="output" rows="3" cols="60"></textarea>
Output with encoded entities (you will not see any change compared to the input)
<textarea id="enc_output" rows="3" cols="60"></textarea>

HTML code box for formatted code

I just thought that unformatted code does not look so nice in my wordpress posts and because I am a self-maker and did not want to install any syntax highlighter I just wrote a little C# program which generates HTML code out of richText code. So I can simply paste code from Visual Studio and then I receive the HTML code to display my code from Visual Studio on any HTML page.
Here you can see the source code of this little tool as an example:

//C# Program that generates HTML-Code out of any programming code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        string Code;
        private void button1_Click(object sender, EventArgs e)
        {
            Code = "";
            Code += "<div class=\"coloredCode\"";
            Code += " style=\"font-family: "+richTextBox1.SelectionFont.FontFamily.Name+";\"";
            Code += "><pre style=\"white-space: pre-wrap;\">";
            System.Drawing.Color oldColor = System.Drawing.Color.Black;
            bool opened = false;
            for (int i = 0; i < richTextBox1.TextLength; i++)
            {
                richTextBox1.Select(i, 1);
                if (richTextBox1.SelectionColor != oldColor)
                {
                    if (i != 0 && opened)
                    {
                        Code += "</span>";
                        opened = false;
                    }
                    if (i != richTextBox1.TextLength - 1 && richTextBox1.SelectionColor!=System.Drawing.Color.Black)
                    {
                        Code += "<span style=\"color: " + System.Drawing.ColorTranslator.ToHtml(richTextBox1.SelectionColor) + ";\">";
                        opened = true;
                    }
                }
                Code += System.Web.HttpUtility.HtmlEncode(richTextBox1.SelectedText);
                oldColor = richTextBox1.SelectionColor;
            }
            if (opened)
            {
                Code += "</span>";
            }
            Code += "</pre></div>";
            System.Windows.Forms.TextBox textbox=new System.Windows.Forms.TextBox();
            textbox.Text = Code;
            textbox.SelectAll();
            textbox.Copy();
            MessageBox.Show("Your HTML-Code was copied to the clipboard", "Copied", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
    }
}

The program can be downloaded here

JavaScript Progress Bar in Windows Style

Here is a progress bar for JavaScript in Windows Style. I was annoyed of the fact that there is no element for a progress bar like there is in C# or C++, I found some progress bars that looked good but they were just gif animations where the percentage could not be set using javascript. So I copied some graphics of the Windows progress bar using C# and used them in HTML/JavaScript for my bar.
Here is an example of the bar:

This is my code:

<script type="text/javascript" language="javascript" src="/Bilder/progressBar/progressBar.js"></script> <script type="text/javascript">
function updateBar()
{
	if(progress < 300)
	{
		progress++;
		setBar('Bar', progress);
		setBarText('Bar', 'Processing: '+Math.round(getPercentageFromWidth(300, progress))+'%');
	}

}
newBar("Bar", 300, "");
setBarText("Bar", "Initializing...");
var progress=0;
setTimeout('setInterval(updateBar, 10);', 5000);
</script>

while this is the content of the progressBar.js file which is included:

/* JavaScript Progress Bar - Windows Style Code written by Birk Blechschmidt, 2011 http://robofan.de This notice has to stay and may not be modified. */
function setBar(bar, pixels)
{
	document.getElementById(bar).style.width=pixels+"px";
}
function setBarText(bar, text)
{
	document.getElementById(bar+"_text").innerHTML=text;
}
function getWidthFromPercentage(barWidth, percentage)
{
	return Math.round(130*percentage/100);
}
function getPercentageFromWidth(barWidth, width)
{
	return width/barWidth*100;
}
function newBar(id, width, imagePath)
{
	if(imagePath.length > 0)
	{
		if(imagePath.substr(imagePath.length-1, 1)!="/")
		{
			imagePath=imagePath+"/";
		}
	}
	var Code='<div class="progressBarContainer" style="border: none; border-spacing: 0; width: '+width+'px; height: 23px; margin: 0; padding: 0; position: relative; top: 0; left: 0;"><div style="border: none; border-spacing: 0; margin: 0; padding: 0;"><img src="'+imagePath+'left.png" style="border: none; border-spacing: 0; margin: 0; padding: 0;" /><img src="'+imagePath+'middle.png" style="border: none; border-spacing: 0; width: '+eval(width-4)+'px; height: 23px; margin: 0; padding: 0;" /><img src="'+imagePath+'right.png" style="border: none; border-spacing: 0; margin: 0; padding: 0;" /></div><div class="greenBar" style="border: none; border-spacing: 0; position: absolute; top: 0px; left: 0px; overflow: hidden; height: 23px; white-space: nowrap; margin: 0; padding: 0; width: 0px;" id="'+id+'"><img src="'+imagePath+'left_green.png" style="border: none; border-spacing: 0; margin: 0; padding: 0;" /><img src="'+imagePath+'middle_green.png" style="border: none; border-spacing: 0; width: '+eval(width-4)+'px; height: 23px; margin: 0; padding: 0;" /><img src="'+imagePath+'right_green.png" style="border: none; border-spacing: 0; margin: 0; padding: 0;" /></div><div id="'+id+'_text" style="position: absolute; top: 1px; left: 0; overflow: hidden; width: '+width+'px; height: 23px; white-space: nowrap; text-align: center; color: black; z-index: 1; font-size: 13px;"></div></div>';
	document.write(Code);
}

I do not think this code needs an explanation.

Here you can download the zip-archive containing the images of the progress bar.

Get access to a protected file or registry key in C#

Some days ago I wanted to create a program which creates a file in a protected folder. Neither the current user nor the administrator had any access to that folder being owned by “TrustedInstaller”. I searched hours in Google trying to find out how to impersonate a user. I did not find anything useful until I found out it is not possible to impersonate “TrustedInstaller” because it is a Windows service. Also in big programming forums nobody could help me. So I was very thankful when I found this page in the web: http://blog.mikeobrien.net/2009/11/taking-ownership-and-setting-admin.html
This is the page of Mike O’Brien who blogs about his computer projects. There I found an article about how to get admin access of any system object. This system object may be a registry key, a file or a printer. At first I was very happy but then I noticed that it is not usable in .Net Framework 2.0. After some minutes I found out that it is not difficult to translate it for usage in .Net 2.0 and have done that here:

using System;
using System.Runtime.InteropServices;
using System.Security;

namespace FilePermissions
{
    class Program
    {
        public static void GrantAdministratorsAccess(string name, SE_OBJECT_TYPE type)
        {
            SID_IDENTIFIER_AUTHORITY sidNTAuthority = SECURITY_NT_AUTHORITY;

            // Create a SID for the BUILTIN\Administrators group.
            IntPtr sidAdmin = IntPtr.Zero;
            AllocateAndInitializeSid(ref sidNTAuthority, 2,
                                     SECURITY_BUILTIN_DOMAIN_RID,
                                     DOMAIN_ALIAS_RID_ADMINS,
                                     0, 0, 0, 0, 0, 0,
                                     ref sidAdmin);

            // Set full control for Administrators.
            EXPLICIT_ACCESS[] explicitAccesss = new EXPLICIT_ACCESS[1];
            explicitAccesss[0].grfAccessPermissions = ACCESS_MASK.GENERIC_ALL;
            explicitAccesss[0].grfAccessMode = ACCESS_MODE.SET_ACCESS;
            explicitAccesss[0].grfInheritance = NO_INHERITANCE;
            explicitAccesss[0].Trustee.TrusteeForm = TRUSTEE_FORM.TRUSTEE_IS_SID;
            explicitAccesss[0].Trustee.TrusteeType = TRUSTEE_TYPE.TRUSTEE_IS_GROUP;
            explicitAccesss[0].Trustee.ptstrName = sidAdmin;

            IntPtr acl = IntPtr.Zero;
            SetEntriesInAcl(1,
                            ref explicitAccesss[0],
                            0,
                            ref acl);

            // Enable the SE_TAKE_OWNERSHIP_NAME privilege.
            IntPtr token = IntPtr.Zero;
            TOKEN_PRIVILEGES tokenPrivileges = new TOKEN_PRIVILEGES();
            OpenProcessToken(GetCurrentProcess(),
                TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out token);

                LUID luid;
                LookupPrivilegeValueA(null, SE_TAKE_OWNERSHIP_NAME, out luid);
                tokenPrivileges.PrivilegeCount = 1;
                tokenPrivileges.Privileges = new LUID_AND_ATTRIBUTES[1];
                tokenPrivileges.Privileges[0].Luid = luid;
                tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

            AdjustTokenPrivileges(token, false, ref tokenPrivileges, 0,
                IntPtr.Zero, IntPtr.Zero);
            CloseHandle(token);

            // Set the owner in the object's security descriptor.
            SetNamedSecurityInfo(
                name,
                type,
                SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION,
                sidAdmin,
                IntPtr.Zero,
                IntPtr.Zero,
                IntPtr.Zero);

            // Disable the SE_TAKE_OWNERSHIP_NAME privilege.
            token = IntPtr.Zero;
            tokenPrivileges = new TOKEN_PRIVILEGES();
            OpenProcessToken(GetCurrentProcess(),
                TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out token);
            AdjustTokenPrivileges(token, false, ref tokenPrivileges, 0,
                IntPtr.Zero, IntPtr.Zero);
            CloseHandle(token);

            // Modify the object's DACL,
            SetNamedSecurityInfo(
                name,
                type,
                SECURITY_INFORMATION.DACL_SECURITY_INFORMATION,
                IntPtr.Zero, IntPtr.Zero,
                acl,
                IntPtr.Zero);

            FreeSid(sidAdmin);
            LocalFree(acl);
        }
        [StructLayoutAttribute(LayoutKind.Sequential)]
        private struct SID_IDENTIFIER_AUTHORITY
        {
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 6, ArraySubType = UnmanagedType.I1)]
            public byte[] Value;
        }

        [StructLayoutAttribute(LayoutKind.Sequential)]
        private struct TRUSTEE
        {
            public System.IntPtr pMultipleTrustee;
            public MULTIPLE_TRUSTEE_OPERATION MultipleTrusteeOperation;
            public TRUSTEE_FORM TrusteeForm;
            public TRUSTEE_TYPE TrusteeType;
            public IntPtr ptstrName;
        }

        [StructLayoutAttribute(LayoutKind.Sequential)]
        private struct EXPLICIT_ACCESS
        {
            public ACCESS_MASK grfAccessPermissions;
            public ACCESS_MODE grfAccessMode;
            public uint grfInheritance;
            public TRUSTEE Trustee;
        }

        [StructLayoutAttribute(LayoutKind.Sequential)]
        private struct TOKEN_PRIVILEGES
        {
            public uint PrivilegeCount;
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 1, ArraySubType = UnmanagedType.Struct)]
            public LUID_AND_ATTRIBUTES[] Privileges;
        }

        [StructLayoutAttribute(LayoutKind.Sequential)]
        private struct LUID_AND_ATTRIBUTES
        {
            public LUID Luid;
            public uint Attributes;
        }

        [StructLayoutAttribute(LayoutKind.Sequential)]
        private struct LUID
        {
            public uint LowPart;
            public int HighPart;
        }

        private enum TRUSTEE_TYPE
        {
            TRUSTEE_IS_GROUP,
        }

        private enum TRUSTEE_FORM
        {
            TRUSTEE_IS_SID,
        }

        private enum MULTIPLE_TRUSTEE_OPERATION { }

        public enum SE_OBJECT_TYPE
        {
            SE_UNKNOWN_OBJECT_TYPE = 0,
            SE_FILE_OBJECT,
            SE_SERVICE,
            SE_PRINTER,
            SE_REGISTRY_KEY,
            SE_LMSHARE,
            SE_KERNEL_OBJECT,
            SE_WINDOW_OBJECT,
            SE_DS_OBJECT,
            SE_DS_OBJECT_ALL,
            SE_PROVIDER_DEFINED_OBJECT,
            SE_WMIGUID_OBJECT,
            SE_REGISTRY_WOW64_32KEY
        }

        [Flags]
        private enum ACCESS_MASK : uint
        {
            GENERIC_ALL = 0x10000000,
        }

        [Flags]
        private enum SECURITY_INFORMATION : uint
        {
            OWNER_SECURITY_INFORMATION = 0x00000001,
            DACL_SECURITY_INFORMATION = 0x00000004,
        }

        private enum ACCESS_MODE
        {
            SET_ACCESS
        }

        private const string SE_TAKE_OWNERSHIP_NAME = "SeTakeOwnershipPrivilege";
        private static SID_IDENTIFIER_AUTHORITY SECURITY_NT_AUTHORITY =
            new SID_IDENTIFIER_AUTHORITY() { Value = new byte[] { 0, 0, 0, 0, 0, 5 } };

        private const UInt32 TOKEN_ADJUST_PRIVILEGES = 0x0020;
        private const int NO_INHERITANCE = 0x0;
        private const int SECURITY_BUILTIN_DOMAIN_RID = 0x00000020;
        private const int DOMAIN_ALIAS_RID_ADMINS = 0x00000220;
        private const int TOKEN_QUERY = 8;
        private const int SE_PRIVILEGE_ENABLED = 2;

        [DllImportAttribute("advapi32.dll", EntryPoint = "OpenProcessToken")]
        [return: MarshalAsAttribute(UnmanagedType.Bool)]
        private static extern bool OpenProcessToken(
            [InAttribute] 
    IntPtr ProcessHandle,
            uint DesiredAccess,
            out IntPtr TokenHandle);

        [DllImportAttribute("advapi32.dll", EntryPoint = "AllocateAndInitializeSid")]
        [return: MarshalAsAttribute(UnmanagedType.Bool)]
        private static extern bool AllocateAndInitializeSid(
            [InAttribute] ref SID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
            byte nSubAuthorityCount,
            uint nSubAuthority0,
            uint nSubAuthority1,
            uint nSubAuthority2,
            uint nSubAuthority3,
            uint nSubAuthority4,
            uint nSubAuthority5,
            uint nSubAuthority6,
            uint nSubAuthority7,
            ref IntPtr pSid);

        [DllImportAttribute("kernel32.dll", EntryPoint = "CloseHandle")]
        [return: MarshalAsAttribute(UnmanagedType.Bool)]
        private static extern bool CloseHandle([InAttribute] IntPtr hObject);

        [DllImportAttribute("kernel32.dll", EntryPoint = "GetCurrentProcess")]
        private static extern IntPtr GetCurrentProcess();

        [DllImportAttribute("advapi32.dll", EntryPoint = "FreeSid")]
        private static extern IntPtr FreeSid([InAttribute] IntPtr pSid);

        [DllImportAttribute("kernel32.dll", EntryPoint = "LocalFree")]
        private static extern IntPtr LocalFree(IntPtr hMem);

        [DllImportAttribute("advapi32.dll", EntryPoint = "LookupPrivilegeValueA")]
        [return: MarshalAsAttribute(UnmanagedType.Bool)]
        private static extern bool LookupPrivilegeValueA(
            [InAttribute] 
    [MarshalAsAttribute(UnmanagedType.LPStr)] 
    string lpSystemName,
    [InAttribute] 
    [MarshalAsAttribute(UnmanagedType.LPStr)] 
    string lpName,
    [OutAttribute] 
    out LUID lpLuid);

        [DllImportAttribute("advapi32.dll", EntryPoint = "AdjustTokenPrivileges")]
        [return: MarshalAsAttribute(UnmanagedType.Bool)]
        private static extern bool AdjustTokenPrivileges(
            [InAttribute()] 
    IntPtr TokenHandle,
            [MarshalAsAttribute(UnmanagedType.Bool)] 
    bool DisableAllPrivileges,
            [InAttribute()] 
    ref TOKEN_PRIVILEGES NewState,
            uint BufferLength,
            IntPtr PreviousState,
            IntPtr ReturnLength);

        [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
        private static extern int SetNamedSecurityInfo(
            string pObjectName,
            SE_OBJECT_TYPE ObjectType,
            SECURITY_INFORMATION SecurityInfo,
            IntPtr psidOwner,
            IntPtr psidGroup,
            IntPtr pDacl,
            IntPtr pSacl);

        [DllImport("Advapi32.dll", EntryPoint = "SetEntriesInAclA",
         CallingConvention = CallingConvention.Winapi,
         SetLastError = true, CharSet = CharSet.Ansi)]
        private static extern uint SetEntriesInAcl(
            int CountofExplicitEntries,
            ref EXPLICIT_ACCESS ea,
            uint OldAcl,
            ref IntPtr NewAcl);
        static void Main(string[] args)
        {
            GrantAdministratorsAccess("Machine\\Key", SE_OBJECT_TYPE.SE_REGISTRY_KEY);
        }
    }
}

Code by Mike O’Brien, Source: http://blog.mikeobrien.net/2009/11/taking-ownership-and-setting-admin.html; Code is modified for usage in .Net 2.0

This code grants admin access to the folder “Test” located on the hard drive “C:”. Now it is possible for the program to edit the directory.
To get access for any registry key the method would look like this:

GrantAdministratorsAccess("Machine\\Key", SE_OBJECT_TYPE.SE_REGISTRY_KEY);

Note that the local machine just has to be called “MACHINE”.

More Visitors through WordPress Blog System

Since I changed my blog system to WordPress, I recognize more visitors. One more thing to say is that already in the first three days two visitors commented my posts although my server had massive problems, while I had only three comments on my old blog – in its total running time. I guess wordpress is friendlier to search engines. I also decided to blog more frequently. The design of my blog looks much better than the old one and it loads much more quickly because of the new server. The WordPress weblog can now be designed more individually and for the administrator there are much more options available.

Greetings from vacations (Turracher Höhe, Austria)

Mehr Besucher durch WordPress-Blogsystem

Seitdem ich mein Blogsystem auf WordPress umgestellt habe, kann ich deutlich mehr Besucher verzeichnen. Außerdem haben an drei Betriebstagen bereits zwei Besucher trotz massiver Serverprobleme meine Beiträge kommentiert, auf meinem alten Blog gab es lediglich drei Kommentare – und das in der Gesamtlaufzeit. Ich nehme an, dass WordPress suchmaschinenfreundlicher ist als der Synology-Blog. Ebenso habe ich mich entschieden, etwas häufiger zu bloggen. Das Design finde ich auch viel besser als das alte und der Blog lädt auch durch den neuen Server viel schneller. Das Weblog lässt sich nun viel individueller gestalten und für den Betreiber gibt es viel mehr Optionen.

Viele Grüße aus dem Urlaub (Turracher Höhe, Österreich)