different minds about different platforms

a blog of Dirk Eisenberg (>)

  Home  |   Contact  |   Syndication    |   Login
  39 Posts | 4 Stories | 7 Comments | 24 Trackbacks

News

Ich hoffe das jeder Besucher in diesem Blog das ein oder andere interessante Thema findet. Als Autor der Beiträge freue ich mich besonders über Feedback in Form von Kommentaren oder auch persönlicher als E-Mail. Dankbar nehme ich Anregungen und Korrekturen von fehlerhaften Inhalten entgegen.

Article Categories

Archives

Post Categories

Image Galleries

Blogs

Links

Saturday, November 01, 2008 #

Daheim auf dem Sofa sitzend habe ich mich eben geärgert das wegen meiner unschönen Netzwerkkonfiguration ich nach jeder OSD Installation den DNS Server auf meinen DC umbiegen muss. Das warum soll hierbei mal keine Rolle spielen. Wenn man also so einen v6 Server sein eigen nennt kann man diesen Schritt ja auch gleich automatisieren.

Folgendes wollte ich mit meinem Script erreichen:

1. Es ist überall einsetzbar und auf jede Netzwerkverbindung anwendbar
2. Tritt ein Fehler auf weil netsh.exe Probleme hat die Einstellungen zu setzen soll die Policyinstanz auf rot gehen
3. Der aufgetretene Fehler soll im LastComment-Feld der Policyinstanz sichtbar sein

Um 1. zu realisieren kommen in enteo v6 nur Installationsparameter in Frage. Daher nutze ich einen Parameter in dem der Name der entsprechenden Netzwerkverbindung steht und einen zweiten in dem die neue DNS-Server-Adresse steht. Diese beiden Installationsparameter müssen bei Zuweisung änderbar markiert werden da man sonst je jedesmal das Paket anfassen muss wenn man einen neuen Wert vergeben möchte.

Um 2. zu realisieren kommt der ab enteo v6.2 zur Verfügung gestellte Befehl ExecuteEx in Betracht. Mit diesem Kommando kann der Rückgabe-Wert eines Prozesses in eine eScript Variable geschrieben werden. Hat man mal den Rückgabewert in einer Variable kann mit Hilfe der "If" Struktur und dem ebenfalls neuen Kommando ExitProcEx die Installation als "failed" markiert werden.

Um jetzt noch 3. realisieren zu können, kann dem Kommand ExitProcEx ein Kommentar mitgegeben werden. In diesem Kommentar wird die Fehlercode-Variable aufgelöst.

HIER findet sich das exportierte Paket für alle die es mal ausprobieren wollen. Das Beispiel hat nicht den Ansprach die besten Lösung für das Wechseln von DNS-Adresse zu sein. Es soll viel mehr zeigen wie man mit den in enteo v6.2 zur  Verfügung gesellten Mitteln den Compliance-Status seiner Policyinstanz beeinflussen kann. Viele externe Installer und Tools geben über diesen Mechanismus Fehlercodes zurück die ausgewertet können.

Sunday, July 27, 2008 #

Jeder der schonmal einen Kernel-Mode-Treiber unter Windows geschrieben hat, kam auch mit dem Problem in Berührung diesen zu Debuggen. Das üblich Modell hierfür ist die Verwendung eines Null-Modem-Kabels und einem zweiten Rechner als Debugger. Zum Glück gibt es VMWare und das ganze kann in zwei virtuellen Maschinen bewerkstelligt werden. Hierfür koppelt man die beiden VMs über einen seriellen Port mit dem Type "Named Pipe". Auch auf der MAC Version ist genau dieses Möglich wie ich nach langem Suchen herausgefunden habe. Den Original-Eintrag findet man hier.

Der Trick dabei ist eigentlich nur das die Oberfläche von VMWare Fusion die benötigten Einstellungen nicht her gibt. Trägt man das ganze in die .vmx-Datei selbst ein funktioniert es. Hier nochmal die Einstellungen:

Auf der Client-Seite:

serial0.present = "TRUE"
serial0.fileType = "pipe"
serial0.pipe.endPoint = "client"
serial0.yieldOnMsrRead = "TRUE"
serial0.startConnected = "TRUE"
serial0.fileName = "/Volumes/Virtual Machines/VMware/Serial/devbox_com1"

und auf der Server-Seite:

serial0.present = "TRUE"
serial0.fileType = "pipe"
serial0.yieldOnMsrRead = "TRUE"
serial0.startConnected = "TRUE"
serial0.fileName = "/Volumes/Virtual Machines/VMware/Serial/devbox_com1"

Sunday, July 20, 2008 #

Schon ganz ungeduldig habe ich den Blog des iphone Dev Teams beobachtet und auf das Release von pwnage 2.0 gewartet. Dieses Tool soll in der Lage sein bei meinem iPhone 2G den jailbreak und unlock durchzuführen. Um die Spannung zu nehmen, es hat geklappt und für alle die keinen MAC daheim haben, gibt es einen Möglichkeit den unlock auch durchzuführen.

Ein kurz Anleitung wie der Prozess durchzuführen ist findet man hier. Im weiteren Verlauf der Kommentare finden sich auch Links zu den Bootloader. Ich wollte eigenlich nur eine Hürde beschreiben. Wie bekommt man sein iPhone in den DFU mode?

1. iPhone über USB andocken
2. iPhone über die Tastekombination Power + Home ausschalten (ca 7s)
3. Power + Home Taste ca zwei weitere Sekunden gedrückt halten
4. Danach die Power-Taste loslassen und Home gedrückt halten bis iTunes das Geräte im Recovery erkennt. Der Monitor des iPhones muss schwarz sein.

Danach befindet sich das iPhone im DFU Mode und kann beliebige Images verdauen. Um ein Image (wie das von pwnage erzeugte) einzuspielen, einfach die alt-Taste (auf MAC) oder die CTRL-Taste gedrückt halten und dann auf Restore in iTunes drücken. Jetzt kann ein beliebiges .ipsw ausgewählt werden. So können auch Windows nutzer ihr iPhone unlocken wenn sie ein passendes .ipsw haben.

 

Monday, April 21, 2008 #

Einige Abende haben mich nun die icht mehr ganz so neuen Virtual Shadow Copy Services beschäftigt. Für alle die genauso wie ich eine Shadow Copy einer Partition anlegen wolle um mit ihrer Platte irgendetwas in einem stabilien Zustand zu bewerkstelligen sollte dieser Code hilfreich sein. Das Ziel des hier abgebildeten Codes soll es sein eine Virtual Shadow Copy einer Partition zu erzeugen und mit Hilfe von Win32-Apis auf diese zuzugreifen. Der Code beinhaltet natürlich viel zu wenig Error-Handling und achtet auch nicht auf die korrekte Freigabe von Resourcen. Nun aber los:

CoInitializeEx( NULL, 0 );
Zuerst muss COM initialisiert wert, dazu muss man wohl nichts mehr sagen.

IVssBackupComponents* pBackupComponents = NULL;
if ( FAILED( CreateVssBackupComponents( &pBackupComponents
) ) )
  return
1;
Um überhaupt mit dem VSS-Api arbeiten zu können wird ein Pointer auf ads BackupComponents-Interface benötigt. Dieses Objekte stellt dann Methoden zur Verfügung um VSS zur Arbeit zu überreden. Wichtig bei allen folgenden Methoden-Aufrufen ist die Reihenfolge. Hier legt Microsoft genaue Abläufe fest die umbedingt eingehalten werden müssen. Wer sich nicht daran hält wird mit Error-Codes bestraft (ich habs probiert).

hr = pBackupComponents->InitializeForBackup( NULL );
Nachdem wir Zugriff auf das BackupComponents-Objekt erhalten haben, ist die erste Amtshandlung dem System zu sagen wir wollen ein Backup machen. Hierzu muss die Methode InitializeForBackup aufgerufen werden. Erst hierdurch können die nachfolgenden Methoden aufgerufen werden.

hr = pBackupComponents->SetContext( VSS_CTX_BACKUP );
Dem System ist im dritten Schritt zu sagen welche Art von Backup und damit welche Art von Snapshot erzeugt werden soll. Hier gibt es verschiedene Möglichkeit, grundsätzlich sind aber zwei zu Unterscheide. Eine Variante bezieht die sogenannten Writer mit ein und die andere eben nicht. Writer stellen Userland-Applikation dar die auf bestimmte Aktionen des VSS-Systems reagieren und vor einem Backup bestimmte Aktionen zu beenden. Datenbanken würden alle wichtigen Informationen noch auf die Platte schreiben damit die Datenbank auch in einem brauchbaren Zustand ist. Hat man Softare die keinen VSS-Support bietet, muss wohl der Weg über Stop-Service und Start-Service eben dieser gegangen werden. Erst danach ist es ratsam eine Shadow-Copy zu erzeugen. Wie man Writer schreibt werde ich einem anderen Eintrag versuchen darzustellen.

IVssAsync* pWriteMetaData = NULL;
hr = pBackupComponents->GatherWriterMetadata( &pWriteMetaData
);
pWriteMetaData->Wait
();
pWriteMetaData->Release
();
Da wir Writer-Aktionen in unser Backup einbeziehen, müssen auch die Meta-Daten über diese abgefragt werden. Hierdurch erlangt das System genau Informationen welche Writer wie und wann benachrichtigt werden müssen. Diese Aktion kann durchaus etwas länger dauer. Aus diesem Grund wird hierfür eine Pointer für assynchrone Operationen zurückgegeben mit dessen Hilf das Ende abgewartet werden kann.

VSS_ID snapshotSetId;
hr = pBackupComponents->StartSnapshotSet( &snapshotSetId
);
VSS sieht die Sicherung des geamten Storage-Systems zu einem Zeitpunkt vor, daher reden wir nicht von einem Snapshot eines spezifischen Volumes sondern eine SnapShot-Set der eine Liste von einzubeziehenden Volumes verwaltet. Dadurch ist es Möglich z.B. die Partition für mdf und ldf in einem Snapshot-Set zu fixieren und später einfach zu sichern.

VSS_ID SnapShotId;
hr = pBackupComponents->AddToSnapshotSet( L"F:\\", GUID_NULL, &SnapShotId
);
Haben wir den Container, das SnapShot-Set angelegt, müssen jetzt noch die einzelnen Targets hinzugefügt werden. Die einfachste Methode ist es via Laufwerksbuchstaben eine ganze Partition hinzuzufügren. Dieser Vorgang kann mehrfach für andere Volumes wiederholt werden.

hr = pBackupComponents->SetBackupState( false, false, VSS_BT_FULL );
Da auch inkrementielle Backups vorgesehen sind, ist noch die Art und Weise des Backups zu definieren. In diesem Beispiel wollen wir ein Full-Backup aller Dateien machen. Es gibt auch die Möglichkeit Dateien einzuschränken.

IVssAsync* pPrepare = NULL;
hr = pBackupComponents->PrepareForBackup( &pPrepare
);
pPrepare->Wait
();
pPrepare->Release
();
Jetzt nähern wir uns dem Punkt der Wahrheit, dem VSS-System wird mitgeteilt das sich alle Writer und Provider auf das Backup vorbereiten müssen. Kurz darauf folgt dann die eigentlich Erzeugung des Snapshots.

IVssAsync* pDoShadowCopy = NULL;
hr = pBackupComponents->DoSnapshotSet( &pDoShadowCopy
);
pDoShadowCopy->Wait
();
pDoShadowCopy->Release
();
Mit der Methode DoSnapshotSet wird dann für jede Komponente des Sets ein SnapShot erzeugt. Hierbei sorgt das Betriebssystem für die Konsistenz der Daten.

VSS_SNAPSHOT_PROP props;
hr = pBackupComponents->GetSnapshotProperties( SnapShotId, &props
);
Nun fehlt nur noch die Information für den Zugriff via Win32-Api. Hierfür stellt die abgerufene Struktur eine Device-Pfad zur Verfügung auf den vie CreateFile und anderen IO-Operation zugegriffen werden kann.

pBackupComponents->Release();
Nur noch das Interface release und fertig.

Hinweis: In diesem Beispiel wurde ein temporärer Snapshot angelegt, d.h. wenn dieser nicht mehr benötigt wird, verschwindet dieser. Auch ein Restart des VSS-Service lässt den Snapshot verschiedenen. Will man persistente Snapshots, müssen die Flags entsprechend umkonfiguriert werden.

Mit dem Tool dosdev lassen sich so erzeugte Snapshots auch mounten und einem Laufwerksbuchstaben zuordnen. Mehr Informationen hierzu gibt es auf folgenden Seiten: 

Ich werde in den nächsten Artikeln versuchen Schritt für Schritt andere Funktionen auf C++-Ebene zu beschreiben. Hierbei werden Themen wie das Schreiben von VSS-Writern und VDS-Hardware-Providern adressiert. 


Saturday, April 19, 2008 #

Ich bekommen immer mal wieder anfragen wie man von einem enteo v6 Objekt wie dem Computer Parameter auslesen kann und diese im Skript verwendet werden. Vor einiger Zeit habe ich dazu mal einen Artikel im enteo-Forum gepostet. Dieser beschreibt nicht nur wie man die Properties ausliest, sondern wie mit Hilfe eines enteo Scripts verschiedene Werte gesetzt werden können.

>> Viel Spass mit dem Artikel <<


Sunday, April 06, 2008 #

Im ersten Teil der enteo Reihe möchte ich ein Feature genau beschreiben was hier und da vielleicht in Vergessenheit geraten ist. Die Möglichkeit Befehle in der enteo Script-Sprache zu klassifizieren gibt es schon sehr lange. Ich glaube die Funktion wurde mit dem NT-Support in das Produkt aufgenommen. Wozu braucht man das aber nun und wie funktioniert es:

Wozu:

Oftmals darf der angemeldete Benutzer nicht viel am System verändern aber das Logon-Verhalten des Benutzer steuert eigentlich indirekt die Installation. Daher gibt es die Möglichkeit Aufgaben an einen Dienst zu delegieren und somit Änderungen die administrative Rechte benötigen durchzuführen.

Wie:

(Fast) Jeder Befehl lässt sich im Scrip-Editor klassifizieren. Hierfür stehen folgende Möglichkeiten zur Verfügung:

  • immer ausführen
  • maschinenbezogen
  • maschinenbezogen per Service
  • userbezigen
  • userbezigen per Service
Für die Bewertung wann welche Klassifizierung verwendet wird, ist wichtig die Trennung zwischen Benutzerteil und Maschinenteil zu verstehen. Jedes enteo Script besteht immer aus einem Benutzer und Maschinenteil, egal ob man das sieht oder nicht. Bei der Installation des Paketes muss jetzt entschieden werde, welche Befehle ausgeführt werden müssen. Es gibt die Möglichkeit das Befehle im Rahmen des Maschinenteils oder im Rahmen des Benutzerteils ausgeführt werden. Diese Entscheidung muss entweder der Service-Installer oder der Auto-Installer, wobei der Service-Installer nur die Maschinenteile installieren kann und keine Benutzerteile da es ja keinen angemeldetet Benutzer gibt. Also wann wird nun was ausgeführt:

immer ausführen:
  • wird durch den ServiceInstaller oder den AutoInstaller ausgeführt
  • wird während der Installation des Benutzerteils als auch des Maschinenteils ausgeführt
  • wird im Kontext des jeweiligen Installers ausgeführt
maschinenbezogen:
  • wird durch den ServiceInstaller oder den AutoInstaller ausgeführt
  • wird nur während der Installation des Maschineteils ausgeführt
  • wird im Kontext des jeweiligen Installers ausgeführt
maschinenbezogen per Service:
  • wird durch den ServiceInstaller oder den AutoInstaller ausgeführt
  • wird nur während der Installation des Maschinenteils ausgeführt
  • wird im Kontext des Services ausgeführt
userbezogen:
  • wird nur durch den AutoInstaller ausgeführt
  • wird nur währned der Installation des Benutzerteils ausgeführt
  • wird im Kontext des AutoInstallers ausgeführt
userbezogen per Service:
  • wird nur durch den AutoInstaller ausgeführt
  • wird nur währned der Installation des Benutzerteils ausgeführt
  • wird im Kontext des Service ausgeführt

Das folgende Beispiel soll das Verhalten verdeutlichen. Ein skript bestehend aus:

MsgBox("Immer ausführen")
MsgBox("Workstationbezogen")
MsgBox("Userbezogen")

wird wie folgt ausgeführt wenn es nocht nicht installiert ist:

Der Benutzer meldet sich an alos muss der Maschinen und der Benutzerteil installiert werden. Es ist ja noch nichts auf dem Client ausgeführt wurden. Es erscheinen also alle 3 Message-Boxen auf dem Bildschirm des Benutzers.

Nach dieser Installation würde sich Benutzer 2 anmelden:

Der Benutzer meldet sich an, wobei jetzt nur noch der Benutzerteil des neuen Benutzers installiert werden muss. Der Maschinenteil ist ja schon auf dem System. Also erscheinen 2 Message-Box auf dem Desktop des Benutzers (MsgBox("Immer ausführen") und MsgBox("Userbezogen")).

Mit diesem Wissen kann man jetzt mal die Wirkung RegLoad-Befehl erforschen, insbesondere wenn dieser auf "Immer ausführen" steht und sowohl Teile in HKEY_CURRENT_USER als auch HKEY_CURRENT_MACHINE verändert. Fragen dazu dürfen gerne als Kommentar gestellt werden.


Ich habe lange überlegt ob ich in diesem Block auch die Produkte meines Arbeitgebers einbeziehen soll und habe mich diese Woche dafür entschieden. Dabei geht es nicht um Werbung für die enteo Produktlinie sondern um interessante Funktionen die dem ein oder anderem Admin das Leben erleichtern werden. Ich werde in unregelmäßigen Abständen interessante Thema aus der enteo Produktfamilie herausgreifen und hoffentlich wertvolle Tips geben. Das ersetzt aber nicht die Schulung, den Support und das enteo Support-Forum.

Sunday, March 02, 2008 #

Jeder der eine standard etch Installation sein eigen nennt kann jetzt entwerder via Apt oder per Download ein Debian-Paket für das iSCSI Enterprise Target 0.4.15  installieren. Ich werde in Zukunft diese Paket immer wieder aktualisieren.

hier gehts zum Paket


Wer selbst mal Pakete erstellen und APT-Repositories aufsetzen möcht, dem helfen vielleicht die folgenden Informationen:

Setting up your own APT repository with upload support

Create Debian Linux packages

Saturday, March 01, 2008 #

Die Nutzung von iSCSI als günstiges SAN kann für viele kleine und mittelständische Unternehmen sehr interessant sein. Durch die Freigabe des Microsoft iSCSI Initiators ist die Nutzung auch von Windows Systemen ohne weiteres möglich. Dieser Artikel über die Implementation eines iSCSI-Targets auf Basis von Debian Linux stellt den ersten Schritt zum eigenen Low-Cost-SAN dar.

>> Artikel lesen <<

Feedback zu Inhalten und Veränderungen ist erwünscht und wird sehr gerne eingearbeitet.

Sunday, February 24, 2008 #

Die Daten aus dem System Management Bios geben Aufschluss über die vorliegende Hardware und können nutzbringend in der eigenen Software verwendet werden. Ich selbst wollte SMBIOS-Daten auch in einer Applikation auf einem Mac Book Pro verwenden. Um diese auslesen zu können habe ich ein wenig suchen müssen. Aus diesem Grund möchte ich hier eine Step-By-Step-Beschreibung zu diesem Thema weitergeben:

Wo findet man die SMBIOS Daten:

In der Dokumentation des Standards findet man einen Hinweis das sich zwischen zwei bestimmten Speicheradressen der Anchor-String "SMBIOS" verbirgt. Konnte dieser String gefunden werden, hat man die Offset-Tabelle für die SMBIOS-Daten im Speicher gefunden.

Wie kommt man an diese Daten:

Für diese einfache Frage ist die Antwort eigentlich auch sehr einfach. Man muss nur den Hauptspeicher des Rechner an der entsprechenden Stelle durchsuchen. Das ist auf alten Betriebssystemen wie DOS einfach möglich, auf modernen Betriebssystemen wie Windows, Linux oder Mac OS X nicht. Hier verwaltet der Kernel den Speicher und somit hat auch nur der Kernel Zugriff auf diesen. User-Space-Prozesse erhalten immer nur virtuelle Speicherseiten, also niemals den zu durchsuchenden Speicherbereich. Um doch an diesen Speicher zu kommen gibt es unter vielen Unix-System, sowie Linux und teilweise Mac  des (k)mem-Device /dev/kmem. Auf dieses kann jedes User-Space-Programm zugreifen und somit auch die SMBIOS-Tabelle lesen. Windows bietet eine enstprechende Raw-Data-Tabelle die über WMI erreichbar ist. Ab Mac OS X 10.4 wurde dieses Device entfernt.

AppleSMBIOS.kext:

Statt sich jetzt eine eigene Kernel-Extension schreiben zu müssen, hat das Apple erledigt. Die AppleSMBIOS-Kernel-Extension bietet als IOService die Möglichkeit auf die SMBIOS-Daten zuzugreifen. Was ist also zu tun:

  1. Wir müssen erstmal einen Komnuikationspunkt zum Darwin-Kernel aufbauen. Hierzu nutzen wir einen Mach-Port (es ist erstmal nicht weiter wichtig mehr darüber zu wissen)

    mach_port_t myMasterPort;
    IOMasterPort(MACH_PORT_NULL, &myMasterPort);
     
  2. Also nächstes muss der AppleSMBIOS-IOService erstmal im System gefunden werden. Dabei werden Services in MAC OS X über eine Service-Identity identifiziert. Folgender Code sucht den SMBIOS-IO-Service:

    CFMutableDictionaryRef        myMatchingDictionary;
    io_object_t                   foundService;

    myMatchingDictionary = IOServiceMatching("AppleSMBIOS");
    foundService = IOServiceGetMatchingService( myMasterPort, myMatchingDictionary );
     
  3. Wurde der Service gefunden kann man mit dem Lesen der SMBIOS-Daten beginnen.

    CFMutableDictionaryRef    properties    = NULL;
    CFDataRef                 smbiosdata    = NULL;
       
    IORegistryEntryCreateCFProperties( foundService,
                                       &properties,
                                       kCFAllocatorDefault,
                                       kNilOptions );


    CFDictionaryGetValueIfPresent( properties,
                                   CFSTR( "SMBIOS" ),
                                   (const void **)&smbiosdata );

     
  4. Jetzt stehen die SMBIOS-Daten zur Verfügung und müsse dem Standard entsprechend verarbeitet werden.


Abschluss:

Scheinbar gibt es hier und da ein kleines Problem mit der Abfrage von SMBIOS-Daten. Besonders wenn man in Verbindung mit netkas versucht Mac OS X auf einer anderen Hardware zu nutzen. Auch gibt es eine spezielle Anpassung um Probleme in Verbindung mit Adobe CS zu vermeiden.                

Thursday, February 07, 2008 #

Mein Kollege René hat mich diese Woche auf eine Aktion der Website Coupondeal hingewiesen. Hierbei soll man für einen Blogeintrag auf seiner WebSite mit einem 10 EUR - Gutschein bei Amazon entlohnt werden. Eigentlich bin ich solchen Sachen immer skeptisch gegenüber eingestellt, wollte aber mal etwas Abwechslung in den ganzen technischen Kram hier bringen. Der Entschluss war gefasst also bin ich gleich mal auf die WebSite vom René und hab mir seinen Beitrag angeschaut (sehr nett). Danach auf die Site von Coupondeal um die Bedingungen zu lesen, ist scheinbar alles sehr einfach. Nur diesen Beitrag schreiben und eine Mail an den Betreiber von Coupondeal. In 2-3 Tagen soll dann der Gutschein kommen (bin gespannt).

Und ja das wichtigste: DEN LINK NICHT VERGESSEN

auch auf einem Apple Mac nutzt man in der Regel dynamische Bibliotheken um komplexer werdende Software in verschiedene Module aufzuteilen. Wie auch unter Linux ist das aber so ein Sache wenn es dann um die Verteilung des gesamten Produkts geht. Die von Windows bekannte Side-by-Side-Execution greift leider nicht und somit such der Library-Loader eben nicht im  lokalen Verzeichnis nach der Datei. Also was tun. Apple hat zu diesem Zweck dsa Konzept der Bundles. Bundles sind eigentlich nur festgesetzte Verzeichnisstrukturen, die sowieso hinter jeder Applikation die mit XCode erzeugt wird, stehen. In diese Struktur wird die Library an eine bestimmte Stelle gelegt und der Build-Prozess angepasst. Hierzu sind folgende Schritte nötig:

1. Library-Settings so anpassen das beim Linken immer relativ vom Verzeichnis des Executables referenziert wird.



Hierfür legt man in den Project-Settings des XCode-Projektes den Install-Path der Library wie folgt fest: @executable_path/../Frameworks/yourlib.dylib.

2. Einfühurng eines Custom-Build-Steps beim Erzeugen der eigentlichen Software einführen um die benötigten Libraries zu kopieren.



Hierfür nehmen wir die Croos-Referenz auf das Library-Projekt aus dem letzen Beitrag wieder her und ziehen die sich darin befindliche .dylib auf den eben erzeugte Custom-Build-Step (sieh Abbildung).

Wird nun das Hauptprojekt erzeugt, entsteht immer ein Applikations-Bundle was via Drag-n-Drop vom Benutzer installiert werden kann ohne das aufwändig Setupskripte Libraries an andere Stellen kopieren müssen. Das ganze ist dann nun nur noch hübsch in ein Disk-Image zu verpacken und fertig für den Rollout.

Sunday, January 27, 2008 #

Nachdem ich die ersten Schritte auf meinem Mac erfolgreiche gegangen bin, rückt das erste Mac OS X - Projekt in Objective-C immer näher. Heute habe ich mich dann mit der korrekten Aufteilung meiner Software in verschiedene Libraries beschäftigt. Nun stand ich vor dem Problem wie sagt man XCode das man auf ein anderes Projekt verweisen möchte und erzeugt dabei eine korrekte Abhängigkeit für den Linker. Dieser soll natürlich die dynamische Library in Abhängigkeit der eingestellten Konfiguration nutzen. Die Antwort ist einfach aber nicht offensichtlich.

1. Cross Project Dependencies

Zuerst muss das referenzierte Projekt in den XCode-Baum eingebaut werden. Hierzu muss lediglich über das Kontext-Menu (Add->Existing Files) das entsprechende ausgewählt werden.

2. Referenziertes Projekt in den Linker einbinden

Jetzt kann das referenzierte Projekt im Tree-View über den kleinen Pfeil aufgeklappt werden. Es werde daduch alle Produkte des Projektes sichbar.

Einfach die entsprechende Library auswählen und zum linken durch den Hacken am rechten Zeilenende setzen:



Danach wird XCode wie erwartet im Debug-Build die Debug-Lib und im Release-Build die Release-Lib anziehen.



Sunday, November 11, 2007 #

Puh, es ist geschafft - Mein erster Computer von Apple ist da. Wie es sich für einen Software-Menschen gehört wurde natürlich gleich XCode installiert um die Fähigkeiten des Cocoa Frameworks und Objective-C auszuloten. In diesem Post möchte ich die Lösung eines Problems beschreiben welches ich erst nach einigem Suchen lösen konnte.

Was ist das Problem?
Jede Applikation im Cocoa Framework arbeitet mit einem NSApplication-Objekt (für die MFC Coder eine Art CWinApp). Jetzt möchte ich als Programmierer während der Initialisierungsphase meiner Applikation Code zur Ausführung bringen. Das ist ganz nützlich um Variable oder ähnliches anzulegen.

Klar wenn man MFC kennt, oder?
Klar dachte ich mir, da ich sowas in MFC-Applikationen schon oft erledigt habe. Einfach das CWinApp-Objekt abgeleitet und in InitInstance meine Sachen erledigt, wäre da nicht die Apple Dokumentation.

Delegates
In der Dokumentation zu NSApplication kann man nachlesen das es sehr gute Gründe geben muss um diese Klasse abzuleiten da hierzu auch einige Funktionen des Frameworks verändert werden müssen. So einfache Dinge wie Variablen initialisieren soll man doch lieber über ein NSApp-Delegate lösen. Gesagt getan und gleich mal etwas über Delegates nachgelesen um auf das nächste Problem zu treffen. Wie bekomme ich die setDelegate-Methode mit meinem Objekt als Parameter so früh ausgeführt?

Die Lösung
Nach langem Suchen und Probieren ist die Lösung doch denkbar einfach. Der Interface-Designer hält eine Objekt mit dem Namen First-Responder. Zusätzlich legt man sich ein Objekt seiner Klasse die als NSApp-Delegate funktionieren soll an. Diese beiden Objekte kann man jetzt in Beziehung setzen (ctrl + Mouse) und erzeugt somit ein Delegate von NSApplication. Über den Aufruf [NSApp->delegate myMessage.....] lässt sich mit dem Objekte auch kommunizieren. Natürlich werden alle Delegate-Nachrichten die Implementiert sind auch vom Framework aus angesprochen.

Sunday, October 21, 2007 #

Heute stand ich vor der Herausforderung mal zu prüfen ob es möglich ist ein Windows-XP via enteo v6 OSD in einer Virtual Box von innoTek aufzusetzen. Dumm an der Geschichte ist nur das die gesamte OSD Infrastruktur auf einem Laptop in VMWare läuft und zu allem Überfluss die gesamte Umgebung Host-Only geschalten ist. Klar bei Protokollen wie DHCP und PXE ist da nötig nur was tun? Virtual Box bietet eine Netzwerkeinstellung die sich Host-Interface nennt. AKtiviert man diese Einstellung erscheint auf dem Host-Computer ein neues TAP-basiertes Netzwerk-Device. Ok nach kurzem Grübeln war die Idee gefasst das Host-Only-Device von VMWare mit dem TAP-Device von Virtual-Box über ein Windows XP MAC-Bridge zu verbinden. Danach sollte ja der ganze Verkehr zwischen diesen Systemen nicht schnell aber sauber transportiert werden.

Gesagt getan. Leider meldet sich der VMWare-Treiber gleich mit einer Fehlermeldung und verweist auf ein Whitepaper. Dieses Papier beschreibt das zum Schutz des Kunden diese Funktion abgeschalten ist damit keine DHCP-Server produktive Netzwerke fluten. Gleichzeitig wird auf Registryeinträge zur Freischaltung  verwiesen.

Nach Überwindung dieser letzten Hürde ist die Bridge ist eingerichtet und virtuelle Gast-Systeme aus der einen Welt können mit Gast-Systemen aus der anderen Welte kommunizieren.