Samstag, 27. August 2011

IP(s) auf Server 2003 gezielt sperren

Hier gibt es ein sehr hilfreiches Step-By-Step Tutorial, wie man mithilfe des IP Security Policy Management einzelne IP-Adressen sperren kann. Z.B. bei anhaltenden brute force Attaken.

Dienstag, 2. August 2011

Liebe geht anders.: Bald geht's los

Liebe geht anders.: Bald geht's los: "Hallo liebe Besucher! Und willkommen in meinem Blog. Ich würde mich sehr freuen, wenn ihr mir ein bisschen Gesellschaft leistet, während ic..."

Endlich hat sich meine Tochter durchgerungen, das öffentlich und regelmäßig zu tun, was sie am besten kann - schreiben. Ihre Art, die Welt und das darauf agierende Ensemble zu beschreiben ist höchst amüsant und manchmal auch sehr berührend. Alle, die bisher etwas von ihr gelesen haben, wollten danach nur noch eins: mehr!

Donnerstag, 30. Juni 2011

Banken vs. Mafia

Bank

Mafia

Lebt ausschließlich von der Arbeit anderer

Zinsen, Provisionen, Beteiligungen

Schutzgeld, Raub

Vernichtet Karriere und Leben von vielen Menschen

Schrottpapiere, faule Kredite,  Staatsanleihen, Rohstoff- Nahrungsmittel-Spekulation

Erpressung, Mord

Betreibt Glückspiel in großem Stil

Hedgefonds,  Investmentbanking, Immobilienfinanzierung, Versicherung

Wettportale, Casinos

Agiert International

Bankenkonzerne, Börsen

Cosa Nostra etc.

Verschleiert die Tätigkeiten

Hochkomplexe Produkte,  interne Deals

Geldwäsche, beteiligt sich damit an regulären Geschäften

Erkauft sich Wohlwollen der Mächtigen

Spenden, kulturelle Förderung, Einladungen, Lobbyismus

Bestechung, Manipulation

Trägt keinerlei gesellschaftliche Verantwortung

Euro-Rettungsschirm (Steuerzahler tragen das Risiko der Banken)

In Teilen doch, da sie ihre Mitglieder und Angehörige fördert und schützt

Entzieht sich der Justiz

Verhindert wirkungsvolle Gesetze durch Drohung, Fehlinformation und Manipulation

Setzt Justiz und Exekutive durch Drohung, Bestechung und Korruption außer Kraft

Ignoriert ethische Werte

Jeder Deal, der Geld bringt, wird gemacht, egal, ob dabei ganze Länder ins Elend rutschen

Nicht ganz. Es wird zwar fast alles gemacht, es gibt aber einen Ehrenkodex.

Bert Brecht: “Was ist ein Einbruch in eine Bank gegen die Gründung einer Bank?” [Dreigroschenroman, 1934]

Sonntag, 1. Mai 2011

UpSert als StoredProcedure oder in interner Tabelle VB .Net

Beim Eintragen von Daten in eine SQL-Tabelle ergibt sich immer wieder die Situation, dass in einer Spalte keine doppelten Werte auftauchen dürfen. Versucht man es trotzdem, reagiert die Datenbank mit einem Fehler. Versucht man umgekehrt anhand dieses Wertes einen Datensatz zu aktualisieren, der nicht vorhanden ist, passiert gar nichts. In beiden Fällen muss man also mindestens zweimal die Datenbank aufrufen um entweder einen neuen Datensatz einzutragen, oder einen bereits vorhandenen zu aktualisieren. Im ersten Fall den Fehler abfangen und danach aktualisieren (UPDATE) im zweiten Fall, auf 0-Ergebnis prüfen und gegebenenfalls einen neuen Datensatz anlegen (INSERT).

Es wäre also hilfreich und würde den Aufwand halbieren, wenn man beides in eine Abfrage bündeln könnte, eine UPSERT-Funktion also, die man als Datenbankskript (StoredProcedure). in der Datenbank speichert. So ein Skript könnte etwa so aussehen:

-- =============================================
-- Author: Peter-W. Fischer
-- Create date: 29.4.2011
-- Description:
-- =============================================
--CREATE TABLE [dbo].[Test](
-- [TestID] [uniqueidentifier] NOT NULL,
-- [TestWert] [nvarchar](200) NOT NULL,
-- [Inserted] [datetime] NOT NULL,
-- [Updated] [datetime] NULL,
-- CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED
--(
-- [TestID] ASC
--)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
--) ON [PRIMARY]


CREATE PROCEDURE [dbo].[TestUpSert]
@TestWert nvarchar(200)
,@Check uniqueidentifier OUTPUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SET @Check =null
BEGIN TRANSACTION
UPDATE dbo.Test WITH(SERIALIZABLE)
set
@Check = TestID
,Updated=GETDATE()

where TestWert = @TestWert

IF @Check is null
BEGIN
set @Check=NEWID();
INSERT dbo.Test (TestID, TestWert, Inserted)
values (@Check, @TestWert, GETDATE())
END
COMMIT TRANSACTION
-- select * from dbo.Test
END

GO


Die Tabelle hat vier Spalten.
  1. TestID (Uniqueidentifier/Primary Key),
  2. TestWert, die keine doppelten Einträge zulässt.(Indiziert!)
  3. Inserted (wird nur beim ersten Eintragen gesetzt) und
  4. Updated (wird bei jeder Aktualisierung gesetzt)
Die Procedure TestUpSert hat zwei Parameter:
  1. TestWert, der neue oder zu aktualisierende Eintrag
  2. Check, ein Rückgabeparameter, der die TestID zur späteren Verwendung enthält
Das Verfahren ist denkbar simpel: zunächst wird der Check-Parameter auf NULL gesetzt. Er dient später als Flag, ob das nachfolgende UPDATE funktioniert hat. Das ist nur der Fall, wenn ein Datensatz mit dem TestWert bereits existiert. In dem Fall wird dort der Updated-Wert aktualisiert und Check bekommt den Wert von TestID.

Falls aber Check nach dem Update immer noch NULL ist, gab es TestWert noch nicht in der Tabelle und wird nun per INSERT eingefügt; dabei wird die Spalte Inserted ebenfalls aktualisiert.

Das ganze wird threadsafe durch die Durchführung in einer Transaction und dem SERIALIZE-Attribut beim UPDATE.

Soweit, so gut.

Zum Testen kann man folgendes Skript verwenden:

DECLARE @Check uniqueidentifier
,@Counter int=0
,@Wert nvarchar(100)
Print 'Start: ' + CONVERT(nvarchar(30), GETDATE(), 126)
WHILE @Counter<100000
BEGIN
SET @Wert='Wert' + CONVERT(nvarchar(10),FLOOR(RAND()*50000))
EXEC dbo.TestUpSert @Wert, @Check OUTPUT

SET @Counter=@Counter+1
END
Print 'Ende: ' + CONVERT(nvarchar(30), GETDATE(), 126)

SELECT * FROM dbo.Test ORDER BY TestWert


Es werden 100.000 Einträge in die Tabelle vorgenommen, wobei der TestWert aus dem Wort 'Wert' und einer Zufallszahl zwischen 0 und 49999 besteht, damit es mit einer 50% Chance zu Updates kommen kann.

Server intern: ~ 50 Sekunden
Die Anfangs - und Endzeit des Skripts wird ausgegeben. Bei mir, auf einem mittelmäßigen Dualcore-PC, braucht das Skipt ca. 50 Sekunden, also im Schnitt etwa eine halbe Millisekunde pro Eintrag, was recht schnell ist.

Leider lässt sich diese Zeit nicht erreichen, wenn man TestUpSert aus einem VB .NET Programm aufruft. Ich habe dort in den Datadesigner die StoredProcedure übernommen, sie ist dort anschließend unter QueriesTableAdapter verfügbar und kann mit einer einfachen Funktion aufgerufen werden:

Dim start As Date = Now
Console.WriteLine("{0:G}: StoredProcedure-Test gestartet.", start)
Using qadap As New dsMMDBTableAdapters.QueriesTableAdapter
Dim i As Integer, id As Guid = Guid.Empty
For i = 1 To 100000
qadap.TestUpSert("Testwert" & Int(Rnd() * 50000), id)
Next
End Using
Console.WriteLine("{0:G}: StoredProcedure-Test beendet. Dauer: {1:0.000} Sekunden", Now, Now.Subtract(start).TotalSeconds)

Aufruf per .NET: ~ 8 Minuten
Im Prinzip passiert hier exakt das selbe wie im obigen Skript; allerdings dauert nun die ganze Aktion über 7 (!) Minuten, also mehr als 8x so lang. Tatsächlich braucht jeder neue Eintrag ein paar Millisekunden länger, der letzte fast 20 Sekunden, obwohl FeldWert in der Tabelle indiziert ist?!

Eine weitere Möglichkeit besteht darin, die Eintragungen zunächst innerhalb des Programms , also direkt im Speicher vorzunehmen und anschließend die gesamte Tabelle in einem einzigen Update in die Datenbank zu schreiben. Dazu könnte man zunächst mit einer [Tabelle].Select-Abfrage testen ob der Wert bereits vorhanden ist und danach entweder updaten oder inserten. Tatsächlich kostet dieses Verfahren ebenfalls sehr viel Zeit, wenn die Zahl der Einträge in die Hunderttausend geht. Erheblich verbessern kann man das, indem man einen virtuelle Index auf die Testwert-Spalte setzt. Das geht, indem man ein Dataview über die Tabelle stülpt, das mit einem Sortierfilter arbeitet:

dvTab = New DataView(Tab)
dvTab.Sort = Tab.TestWertColumn.ColumnName

Dann sieht die eigentliche interne UpSert-Funktion so aus:

Public Function Upsert(ByVal Testwert As String) As dsMMDB.TestRow
Upsert = Nothing
Try
Dim rws() As DataRowView = dvTab.FindRows(Testwert)
Dim rw As dsMMDB.TestRow = Nothing
If rws Is Nothing Or rws.Length = 0 Then
rw = Tab.NewTestRow
rw.TestID = Guid.NewGuid
rw.TestWert = Testwert
rw.Inserted = Now
Tab.AddTestRow(rw)
Else
rw = rws(0).Row
rw.Updated = Now
End If

Return rw
Catch ex As Exception

End Try
End Function

.Net intern, dann DB-Update: ~ 4 Minuten
Die braucht, was kaum überrascht, für das interne Eintragen von 100.000 Werten nur knapp 5 Sekunden, allerdings braucht das Updaten der Datenbank dann zusätzliche 4 Minuten. Das sind aber immerhin nur noch etwas mehr als die Hälfte der Zeit, die der Aufruf der StoredProcedure braucht.

Aufgrund dieser Ergebnisse, würde ich also immer die letzte Methode bevorzugen, wenn es darum geht, eine große Menge von Daten in kurzer Zeit entweder zu aktualisieren oder zu insertieren. Der Nachteil der internen Methode ist allerdings, dass Daten solange verloren gehen können, solange sie nicht komplett in die Datenbank geschrieben wurden. Wenn es also vor allem um Datensicherheit geht, ist der Aufruf der StoredProcedure wohl unumgänglich.

Warum dieses Verfahren allerdings so 'teuer', also zeitintensiv ist, konnte ich bisher auch nicht erklären.

Falls jemand was weiß - bitte posten!


Samstag, 23. April 2011

Unsignierte Treiber in Server 2008 - unsigned driver server 2008

Man kann auf dem Server 2008 keine Treiber mehr installieren, die nicht signiert sind. Einerseits aus Sicherheitsgründen verständlich, andererseits in der einen oder anderen Situation schlicht ärgerlich. Z.B. wenn man streamen und dafür eine virtuelle Audiokarte installieren will, weil die meisten Server überhaupt keine Audiohardware haben. Noch sind die meisten dieser virtuellen Treiber aber unsigniert. Was also tun?

Hier die Lösung (hat zumindest bei mir funktioniert):

Command-Fenster öffnen:

dann erst dies:
bcdedit /set loadoptions DDISABLE_INTEGRITY_CHECKS
dann das hier:
bcdedit /set Testsigning on
eingeben und jeweils mit RETURN bestätigen.
In beiden Fällen sollte es eine Erfolgsmeldung geben.

Danach unbedingt den Server neu starten. Danach sollte rechts unten auf dem Desktop die Server Version und "Testmodus" stehen. Nun kann man auch unsignierte Treiber installieren (dazu im Warn-Dialog einfach 'trotzdem installieren' anwählen!)

Dienstag, 22. März 2011

Cubase 6: Video-Import funktioniert nicht! Lösung gefunden!

Unglaublich: heute bekomme ich Antwort von Steinberg, ich solle doch mal in deren Knowledgebase schauen, da stünde drin, wie es geht. Wo habe ich wohl zuerst reingeschaut? Und wo gibt es keine Lösung? Richtig: in der Cubase Knowledgebase! Aber ich gebe nun mal nicht so schnell auf und habe mich an vergleichbare Probleme mit anderen Programmen erinnert und siehe da, ich hab es gefunden:

in Windows 7 ist nämlich standardmäßig UAC (User Acces Control) eingeschaltet, die dafür sorgt, das installierte Programme in der Regel nicht mit Administratorrechten laufen, um Schadsoftware von sensiblen Bereichen abzuhalten. Das ist durchaus sinnvoll. Allerdings scheint die UAC bei Cubase 6 die Initialisierung der Videotreiber zu verhindern. Daher kommt, egal welche Video-Datei man laden will, immer eine Fehlermeldung. Um das zu ändern, muss das Programm mindestens einmal im Administrator-Modus laufen. Dazu mit der rechten Maustaste auf das Cubase-Symbol klicken und im Menü 'als Administrator ausführen' auswählen. Danach wird die Initialisierung der Treiber erstmalig korrekt durchgeführt und es können Videodateien geladen werden. Anschließend kann das Programm dann wieder normal ohne Admin-Rechte gestartet und es können problemlos Videodateien geladen werden!

Ich hoffe nun, dass die hilfreichen Steinberg-Kollegen diese Lösung in ihre Knowledgebase übernehmen, damit andere nicht mehr verzweifeln müssen.

Montag, 21. März 2011

Cubase 6: Video-Import funktioniert nicht!

Schon ärgerlich, wenn man sich die neueste Version von Steinbergs Sequenzer für knapp 600€ kauft um Filmmusik zu vertonen und dann feststellt, dass der Video-Import nicht mehr funktioniert.

Besonders ärgerlich: auf demselben Rechner läuft die ältere Version SX2 problemlos und zeigt sowohl Quiktime als auch MPEG-Videos jeder denkbaren Kompression und Größe.

Am ärgerlichsten aber ist der Service von Steinberg. Ich habe da nun bereits zweimal innerhalb von 10 Tagen hingeschrieben und um Hilfe gebeten, außer einer Bestätigungsmail kam bisher absolut nichts. Ich denke, bei einer derart teuren Profisoftware müsste für registrierte Kunden mehr drin sein.

Im Netz finden sich viele, die dasselbe Probleme aber auch keine Lösung haben. Und auch in Steinbergs Knowledgebase steht nur, dass ab Version 5 nur noch Quicktime 7 unterstützt wird, was aber Blödsinn ist, da ich genau diese Version auf meinem Rechner habe und alle Filme im standalone Quicktime-Player reibungslos laufen. Es handelt sich also ganz klar um einen Bug in der Cubase Software, den die Leute dort scheinbar aussitzen wollen.

Mal gucken, was passiert, wenn man mit Nachdruck auf Nachbesserung bzw. Wandlung dringt, was nach dem Verbraucherrecht hierzulande Teil des Kaufvertrages ist.

Donnerstag, 10. März 2011

Playlist Converter for Zen X-Fi 2 MP3-Player

The X-fi 2 is undoubtly one of the best MP3 players in it's price segment. Except one thing: you cannot transfer standard m3u playlists to the player, allthoug ZEN stores them in the same fortmat internally. But with some modifications that makes it very hard to do it manually. Since the playlists are simple text files you can easely check whats going on. First the player stores all music that you transfer to it into a special foldr structure startin with the root folder MUSIC, then artist, then album. So the references in the internal playlists are relativ to the root folder. Second it converts the filenames to the old DOS standard, that means, they are shortend to eight letters using the ~ character and number if there are sveral files startin with the same eight letters. It would be a pain to change those names manually and is of course failure proned. But since I'm a .NET programmer I wrote a little program for myself that could be useful for everybody else using the Zen. The process is simple an straightforwar: create your playlist as usual (preferrable with winamp), copy the neccessary files to the Zen (it will then store them in the right folders itself). Then open my program, locate the ZEN, load the playlist, the program will check if and how many of the files are on the ZEN, then convert. Ready.

If you are interested, mail to my facebook account. If there are enough people, I will put it on my online storage for public access.